Loading drivers/gpu/drm/msm/sde/sde_encoder.c +132 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,33 @@ enum sde_enc_rc_states { SDE_ENC_RC_STATE_IDLE }; /* rgb to yuv color space conversion matrix */ static struct sde_csc_cfg sde_csc_10bit_convert[SDE_MAX_CSC] = { [SDE_CSC_RGB2YUV_601L] = { { TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032), TO_S15D16(0xffb4), TO_S15D16(0xff6b), TO_S15D16(0x00e1), TO_S15D16(0x00e1), TO_S15D16(0xff44), TO_S15D16(0xffdb), }, { 0x0, 0x0, 0x0,}, { 0x0040, 0x0200, 0x0200,}, { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,}, { 0x0040, 0x03ac, 0x0040, 0x03c0, 0x0040, 0x03c0,}, }, [SDE_CSC_RGB2YUV_601FR] = { { TO_S15D16(0x0099), TO_S15D16(0x012d), TO_S15D16(0x003a), TO_S15D16(0xffaa), TO_S15D16(0xff56), TO_S15D16(0x0100), TO_S15D16(0x0100), TO_S15D16(0xff2a), TO_S15D16(0xffd6), }, { 0x0, 0x0, 0x0,}, { 0x0000, 0x0200, 0x0200,}, { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,}, { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,}, }, }; /** * struct sde_encoder_virt - virtual encoder. Container of one or more physical * encoders. Virtual encoder manages one "logical" display. Physical Loading Loading @@ -5128,3 +5155,108 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc) return 0; } /** * sde_encoder_phys_setup_cdm - setup chroma down block * @phys_enc: Pointer to physical encoder * @output_type: HDMI/WB * @format: Output format * @roi: Output size */ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, const struct sde_format *format, u32 output_type, struct sde_rect *roi) { struct drm_encoder *encoder = phys_enc->parent; struct sde_encoder_virt *sde_enc = NULL; struct sde_hw_cdm *hw_cdm = phys_enc->hw_cdm; struct sde_hw_cdm_cfg *cdm_cfg = &phys_enc->cdm_cfg; int ret; u32 csc_type = 0; if (!encoder) { SDE_ERROR("invalid encoder\n"); return; } sde_enc = to_sde_encoder_virt(encoder); if (!SDE_FORMAT_IS_YUV(format)) { SDE_DEBUG_ENC(sde_enc, "[cdm_disable fmt:%x]\n", format->base.pixel_format); if (hw_cdm && hw_cdm->ops.disable) hw_cdm->ops.disable(hw_cdm); return; } memset(cdm_cfg, 0, sizeof(struct sde_hw_cdm_cfg)); cdm_cfg->output_width = roi->w; cdm_cfg->output_height = roi->h; cdm_cfg->output_fmt = format; cdm_cfg->output_type = output_type; cdm_cfg->output_bit_depth = SDE_FORMAT_IS_DX(format) ? CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT; /* enable 10 bit logic */ switch (cdm_cfg->output_fmt->chroma_sample) { case SDE_CHROMA_RGB: cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; case SDE_CHROMA_H2V1: cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; case SDE_CHROMA_420: cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE; break; case SDE_CHROMA_H1V2: default: SDE_ERROR("unsupported chroma sampling type\n"); cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; } SDE_DEBUG_ENC(sde_enc, "[cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n", 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 (output_type == CDM_CDWN_OUTPUT_HDMI) csc_type = SDE_CSC_RGB2YUV_601FR; else if (output_type == CDM_CDWN_OUTPUT_WB) csc_type = SDE_CSC_RGB2YUV_601L; if (hw_cdm && hw_cdm->ops.setup_csc_data) { ret = hw_cdm->ops.setup_csc_data(hw_cdm, &sde_csc_10bit_convert[csc_type]); if (ret < 0) { SDE_ERROR("failed to setup CSC %d\n", ret); return; } } if (hw_cdm && hw_cdm->ops.setup_cdwn) { ret = hw_cdm->ops.setup_cdwn(hw_cdm, cdm_cfg); if (ret < 0) { SDE_ERROR("failed to setup CDM %d\n", ret); return; } } if (hw_cdm && hw_cdm->ops.enable) { ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg); if (ret < 0) { SDE_ERROR("failed to enable CDM %d\n", ret); return; } } } drivers/gpu/drm/msm/sde/sde_encoder_phys.h +2 −2 Original line number Diff line number Diff line Loading @@ -493,8 +493,8 @@ struct sde_encoder_phys *sde_encoder_phys_wb_init( #endif void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, struct drm_framebuffer *fb, const struct sde_format *format, struct sde_rect *wb_roi); const struct sde_format *format, u32 output_type, struct sde_rect *roi); /** * sde_encoder_helper_trigger_flush - control flush helper function Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +49 −3 Original line number Diff line number Diff line Loading @@ -385,17 +385,20 @@ static void sde_encoder_phys_vid_setup_timing_engine( SDE_DEBUG_VIDENC(vid_enc, "enabling mode:\n"); drm_mode_debug_printmodeline(&mode); if (phys_enc->split_role != ENC_ROLE_SOLO) { if (phys_enc->split_role != ENC_ROLE_SOLO || (mode.private_flags & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)) { mode.hdisplay >>= 1; mode.htotal >>= 1; mode.hsync_start >>= 1; mode.hsync_end >>= 1; mode.hskew >>= 1; SDE_DEBUG_VIDENC(vid_enc, "split_role %d, halve horizontal %d %d %d %d\n", "split_role %d, halve horizontal %d %d %d %d %d\n", phys_enc->split_role, mode.hdisplay, mode.htotal, mode.hsync_start, mode.hsync_end); mode.hsync_start, mode.hsync_end, mode.hskew); } if (!phys_enc->vfp_cached) { Loading Loading @@ -590,6 +593,9 @@ static void sde_encoder_phys_vid_mode_set( return; } phys_enc->hw_ctl = NULL; phys_enc->hw_cdm = NULL; rm = &phys_enc->sde_kms->rm; vid_enc = to_sde_encoder_phys_vid(phys_enc); Loading @@ -615,6 +621,20 @@ static void sde_encoder_phys_vid_mode_set( } _sde_encoder_phys_vid_setup_irq_hw_idx(phys_enc); /* CDM is optional */ sde_rm_init_hw_iter(&iter, phys_enc->parent->base.id, SDE_HW_BLK_CDM); for (i = 0; i <= instance; i++) { sde_rm_get_hw(rm, &iter); if (i == instance) phys_enc->hw_cdm = (struct sde_hw_cdm *) iter.hw; } if (IS_ERR(phys_enc->hw_cdm)) { SDE_ERROR("CDM required but not allocated: %ld\n", PTR_ERR(phys_enc->hw_cdm)); phys_enc->hw_cdm = NULL; } } static int sde_encoder_phys_vid_control_vblank_irq( Loading Loading @@ -713,6 +733,9 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) struct sde_encoder_phys_vid *vid_enc; struct sde_hw_intf *intf; struct sde_hw_ctl *ctl; struct sde_hw_cdm *hw_cdm = NULL; struct drm_display_mode mode; const struct sde_format *fmt = NULL; u32 flush_mask = 0; if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev || Loading @@ -721,7 +744,9 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) SDE_ERROR("invalid encoder/device\n"); return; } hw_cdm = phys_enc->hw_cdm; priv = phys_enc->parent->dev->dev_private; mode = phys_enc->cached_mode; vid_enc = to_sde_encoder_phys_vid(phys_enc); intf = vid_enc->hw_intf; Loading Loading @@ -765,7 +790,21 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) goto skip_flush; } if (mode.private_flags & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420) fmt = sde_get_sde_format(DRM_FORMAT_YUV420); if (fmt) { struct sde_rect hdmi_roi; hdmi_roi.w = mode.hdisplay; hdmi_roi.h = mode.vdisplay; sde_encoder_phys_setup_cdm(phys_enc, fmt, CDM_CDWN_OUTPUT_HDMI, &hdmi_roi); } ctl->ops.get_bitmask_intf(ctl, &flush_mask, intf->idx); if (ctl->ops.get_bitmask_cdm && hw_cdm) ctl->ops.get_bitmask_cdm(ctl, &flush_mask, hw_cdm->idx); ctl->ops.update_pending_flush(ctl, flush_mask); skip_flush: Loading Loading @@ -814,6 +853,8 @@ static void sde_encoder_phys_vid_get_hw_resources( SDE_DEBUG_VIDENC(vid_enc, "\n"); hw_res->intfs[vid_enc->hw_intf->idx - INTF_0] = INTF_MODE_VIDEO; hw_res->needs_cdm = true; SDE_DEBUG_DRIVER("[vid] needs_cdm=%d\n", hw_res->needs_cdm); } static int _sde_encoder_phys_vid_wait_for_vblank( Loading Loading @@ -987,6 +1028,11 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) } sde_encoder_phys_vid_control_vblank_irq(phys_enc, false); } if (phys_enc->hw_cdm && phys_enc->hw_cdm->ops.disable) { SDE_DEBUG_DRIVER("[cdm_disable]\n"); phys_enc->hw_cdm->ops.disable(phys_enc->hw_cdm); } exit: phys_enc->vfp_cached = 0; phys_enc->enable_state = SDE_ENC_DISABLED; Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c +2 −120 Original line number Diff line number Diff line Loading @@ -30,24 +30,6 @@ #define WBID(wb_enc) \ ((wb_enc && wb_enc->wb_dev) ? wb_enc->wb_dev->wb_idx - WB_0 : -1) #define TO_S15D16(_x_) ((_x_) << 7) /** * sde_rgb2yuv_601l - rgb to yuv color space conversion matrix * */ static struct sde_csc_cfg sde_encoder_phys_wb_rgb2yuv_601l = { { TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032), TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1), TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc) }, { 0x00, 0x00, 0x00 }, { 0x0040, 0x0200, 0x0200 }, { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff }, { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 }, }; /** * sde_encoder_phys_wb_is_master - report wb always as master encoder */ Loading Loading @@ -153,107 +135,6 @@ static void sde_encoder_phys_wb_set_qos_remap( sde_vbif_set_qos_remap(phys_enc->sde_kms, &qos_params); } /** * sde_encoder_phys_setup_cdm - setup chroma down block * @phys_enc: Pointer to physical encoder * @fb: Pointer to output framebuffer * @format: Output format */ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, struct drm_framebuffer *fb, const struct sde_format *format, struct sde_rect *wb_roi) { struct sde_hw_cdm *hw_cdm; struct sde_hw_cdm_cfg *cdm_cfg; int ret; if (!phys_enc || !format) return; cdm_cfg = &phys_enc->cdm_cfg; hw_cdm = phys_enc->hw_cdm; if (!hw_cdm) return; if (!SDE_FORMAT_IS_YUV(format)) { SDE_DEBUG("[cdm_disable fmt:%x]\n", format->base.pixel_format); if (hw_cdm && hw_cdm->ops.disable) hw_cdm->ops.disable(hw_cdm); return; } memset(cdm_cfg, 0, sizeof(struct sde_hw_cdm_cfg)); if (!wb_roi) return; cdm_cfg->output_width = wb_roi->w; cdm_cfg->output_height = wb_roi->h; cdm_cfg->output_fmt = format; cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB; cdm_cfg->output_bit_depth = SDE_FORMAT_IS_DX(format) ? CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT; /* enable 10 bit logic */ switch (cdm_cfg->output_fmt->chroma_sample) { case SDE_CHROMA_RGB: cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; case SDE_CHROMA_H2V1: cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; case SDE_CHROMA_420: cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE; break; case SDE_CHROMA_H1V2: default: SDE_ERROR("unsupported chroma sampling type\n"); cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; } SDE_DEBUG("[cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n", 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 && hw_cdm->ops.setup_csc_data) { ret = hw_cdm->ops.setup_csc_data(hw_cdm, &sde_encoder_phys_wb_rgb2yuv_601l); if (ret < 0) { SDE_ERROR("failed to setup CSC %d\n", ret); return; } } if (hw_cdm && hw_cdm->ops.setup_cdwn) { ret = hw_cdm->ops.setup_cdwn(hw_cdm, cdm_cfg); if (ret < 0) { SDE_ERROR("failed to setup CDM %d\n", ret); return; } } if (hw_cdm && hw_cdm->ops.enable) { ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg); if (ret < 0) { SDE_ERROR("failed to enable CDM %d\n", ret); return; } } } /** * sde_encoder_phys_wb_setup_fb - setup output framebuffer * @phys_enc: Pointer to physical encoder Loading Loading @@ -831,7 +712,8 @@ static void sde_encoder_phys_wb_setup( sde_encoder_phys_wb_set_qos_remap(phys_enc); sde_encoder_phys_setup_cdm(phys_enc, fb, wb_enc->wb_fmt, wb_roi); sde_encoder_phys_setup_cdm(phys_enc, wb_enc->wb_fmt, CDM_CDWN_OUTPUT_WB, wb_roi); sde_encoder_phys_wb_setup_fb(phys_enc, fb, wb_roi); Loading drivers/gpu/drm/msm/sde/sde_hw_cdm.c +2 −2 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, 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 @@ -230,7 +230,7 @@ int sde_hw_cdm_enable(struct sde_hw_cdm *ctx, return -EINVAL; if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) { if (fmt->chroma_sample != SDE_CHROMA_H1V2) if (fmt->chroma_sample == SDE_CHROMA_H1V2) return -EINVAL; /*unsupported format */ opmode = BIT(0); opmode |= (fmt->chroma_sample << 1); Loading Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +132 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,33 @@ enum sde_enc_rc_states { SDE_ENC_RC_STATE_IDLE }; /* rgb to yuv color space conversion matrix */ static struct sde_csc_cfg sde_csc_10bit_convert[SDE_MAX_CSC] = { [SDE_CSC_RGB2YUV_601L] = { { TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032), TO_S15D16(0xffb4), TO_S15D16(0xff6b), TO_S15D16(0x00e1), TO_S15D16(0x00e1), TO_S15D16(0xff44), TO_S15D16(0xffdb), }, { 0x0, 0x0, 0x0,}, { 0x0040, 0x0200, 0x0200,}, { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,}, { 0x0040, 0x03ac, 0x0040, 0x03c0, 0x0040, 0x03c0,}, }, [SDE_CSC_RGB2YUV_601FR] = { { TO_S15D16(0x0099), TO_S15D16(0x012d), TO_S15D16(0x003a), TO_S15D16(0xffaa), TO_S15D16(0xff56), TO_S15D16(0x0100), TO_S15D16(0x0100), TO_S15D16(0xff2a), TO_S15D16(0xffd6), }, { 0x0, 0x0, 0x0,}, { 0x0000, 0x0200, 0x0200,}, { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,}, { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,}, }, }; /** * struct sde_encoder_virt - virtual encoder. Container of one or more physical * encoders. Virtual encoder manages one "logical" display. Physical Loading Loading @@ -5128,3 +5155,108 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc) return 0; } /** * sde_encoder_phys_setup_cdm - setup chroma down block * @phys_enc: Pointer to physical encoder * @output_type: HDMI/WB * @format: Output format * @roi: Output size */ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, const struct sde_format *format, u32 output_type, struct sde_rect *roi) { struct drm_encoder *encoder = phys_enc->parent; struct sde_encoder_virt *sde_enc = NULL; struct sde_hw_cdm *hw_cdm = phys_enc->hw_cdm; struct sde_hw_cdm_cfg *cdm_cfg = &phys_enc->cdm_cfg; int ret; u32 csc_type = 0; if (!encoder) { SDE_ERROR("invalid encoder\n"); return; } sde_enc = to_sde_encoder_virt(encoder); if (!SDE_FORMAT_IS_YUV(format)) { SDE_DEBUG_ENC(sde_enc, "[cdm_disable fmt:%x]\n", format->base.pixel_format); if (hw_cdm && hw_cdm->ops.disable) hw_cdm->ops.disable(hw_cdm); return; } memset(cdm_cfg, 0, sizeof(struct sde_hw_cdm_cfg)); cdm_cfg->output_width = roi->w; cdm_cfg->output_height = roi->h; cdm_cfg->output_fmt = format; cdm_cfg->output_type = output_type; cdm_cfg->output_bit_depth = SDE_FORMAT_IS_DX(format) ? CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT; /* enable 10 bit logic */ switch (cdm_cfg->output_fmt->chroma_sample) { case SDE_CHROMA_RGB: cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; case SDE_CHROMA_H2V1: cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; case SDE_CHROMA_420: cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE; break; case SDE_CHROMA_H1V2: default: SDE_ERROR("unsupported chroma sampling type\n"); cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; } SDE_DEBUG_ENC(sde_enc, "[cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n", 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 (output_type == CDM_CDWN_OUTPUT_HDMI) csc_type = SDE_CSC_RGB2YUV_601FR; else if (output_type == CDM_CDWN_OUTPUT_WB) csc_type = SDE_CSC_RGB2YUV_601L; if (hw_cdm && hw_cdm->ops.setup_csc_data) { ret = hw_cdm->ops.setup_csc_data(hw_cdm, &sde_csc_10bit_convert[csc_type]); if (ret < 0) { SDE_ERROR("failed to setup CSC %d\n", ret); return; } } if (hw_cdm && hw_cdm->ops.setup_cdwn) { ret = hw_cdm->ops.setup_cdwn(hw_cdm, cdm_cfg); if (ret < 0) { SDE_ERROR("failed to setup CDM %d\n", ret); return; } } if (hw_cdm && hw_cdm->ops.enable) { ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg); if (ret < 0) { SDE_ERROR("failed to enable CDM %d\n", ret); return; } } }
drivers/gpu/drm/msm/sde/sde_encoder_phys.h +2 −2 Original line number Diff line number Diff line Loading @@ -493,8 +493,8 @@ struct sde_encoder_phys *sde_encoder_phys_wb_init( #endif void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, struct drm_framebuffer *fb, const struct sde_format *format, struct sde_rect *wb_roi); const struct sde_format *format, u32 output_type, struct sde_rect *roi); /** * sde_encoder_helper_trigger_flush - control flush helper function Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +49 −3 Original line number Diff line number Diff line Loading @@ -385,17 +385,20 @@ static void sde_encoder_phys_vid_setup_timing_engine( SDE_DEBUG_VIDENC(vid_enc, "enabling mode:\n"); drm_mode_debug_printmodeline(&mode); if (phys_enc->split_role != ENC_ROLE_SOLO) { if (phys_enc->split_role != ENC_ROLE_SOLO || (mode.private_flags & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)) { mode.hdisplay >>= 1; mode.htotal >>= 1; mode.hsync_start >>= 1; mode.hsync_end >>= 1; mode.hskew >>= 1; SDE_DEBUG_VIDENC(vid_enc, "split_role %d, halve horizontal %d %d %d %d\n", "split_role %d, halve horizontal %d %d %d %d %d\n", phys_enc->split_role, mode.hdisplay, mode.htotal, mode.hsync_start, mode.hsync_end); mode.hsync_start, mode.hsync_end, mode.hskew); } if (!phys_enc->vfp_cached) { Loading Loading @@ -590,6 +593,9 @@ static void sde_encoder_phys_vid_mode_set( return; } phys_enc->hw_ctl = NULL; phys_enc->hw_cdm = NULL; rm = &phys_enc->sde_kms->rm; vid_enc = to_sde_encoder_phys_vid(phys_enc); Loading @@ -615,6 +621,20 @@ static void sde_encoder_phys_vid_mode_set( } _sde_encoder_phys_vid_setup_irq_hw_idx(phys_enc); /* CDM is optional */ sde_rm_init_hw_iter(&iter, phys_enc->parent->base.id, SDE_HW_BLK_CDM); for (i = 0; i <= instance; i++) { sde_rm_get_hw(rm, &iter); if (i == instance) phys_enc->hw_cdm = (struct sde_hw_cdm *) iter.hw; } if (IS_ERR(phys_enc->hw_cdm)) { SDE_ERROR("CDM required but not allocated: %ld\n", PTR_ERR(phys_enc->hw_cdm)); phys_enc->hw_cdm = NULL; } } static int sde_encoder_phys_vid_control_vblank_irq( Loading Loading @@ -713,6 +733,9 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) struct sde_encoder_phys_vid *vid_enc; struct sde_hw_intf *intf; struct sde_hw_ctl *ctl; struct sde_hw_cdm *hw_cdm = NULL; struct drm_display_mode mode; const struct sde_format *fmt = NULL; u32 flush_mask = 0; if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev || Loading @@ -721,7 +744,9 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) SDE_ERROR("invalid encoder/device\n"); return; } hw_cdm = phys_enc->hw_cdm; priv = phys_enc->parent->dev->dev_private; mode = phys_enc->cached_mode; vid_enc = to_sde_encoder_phys_vid(phys_enc); intf = vid_enc->hw_intf; Loading Loading @@ -765,7 +790,21 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) goto skip_flush; } if (mode.private_flags & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420) fmt = sde_get_sde_format(DRM_FORMAT_YUV420); if (fmt) { struct sde_rect hdmi_roi; hdmi_roi.w = mode.hdisplay; hdmi_roi.h = mode.vdisplay; sde_encoder_phys_setup_cdm(phys_enc, fmt, CDM_CDWN_OUTPUT_HDMI, &hdmi_roi); } ctl->ops.get_bitmask_intf(ctl, &flush_mask, intf->idx); if (ctl->ops.get_bitmask_cdm && hw_cdm) ctl->ops.get_bitmask_cdm(ctl, &flush_mask, hw_cdm->idx); ctl->ops.update_pending_flush(ctl, flush_mask); skip_flush: Loading Loading @@ -814,6 +853,8 @@ static void sde_encoder_phys_vid_get_hw_resources( SDE_DEBUG_VIDENC(vid_enc, "\n"); hw_res->intfs[vid_enc->hw_intf->idx - INTF_0] = INTF_MODE_VIDEO; hw_res->needs_cdm = true; SDE_DEBUG_DRIVER("[vid] needs_cdm=%d\n", hw_res->needs_cdm); } static int _sde_encoder_phys_vid_wait_for_vblank( Loading Loading @@ -987,6 +1028,11 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc) } sde_encoder_phys_vid_control_vblank_irq(phys_enc, false); } if (phys_enc->hw_cdm && phys_enc->hw_cdm->ops.disable) { SDE_DEBUG_DRIVER("[cdm_disable]\n"); phys_enc->hw_cdm->ops.disable(phys_enc->hw_cdm); } exit: phys_enc->vfp_cached = 0; phys_enc->enable_state = SDE_ENC_DISABLED; Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c +2 −120 Original line number Diff line number Diff line Loading @@ -30,24 +30,6 @@ #define WBID(wb_enc) \ ((wb_enc && wb_enc->wb_dev) ? wb_enc->wb_dev->wb_idx - WB_0 : -1) #define TO_S15D16(_x_) ((_x_) << 7) /** * sde_rgb2yuv_601l - rgb to yuv color space conversion matrix * */ static struct sde_csc_cfg sde_encoder_phys_wb_rgb2yuv_601l = { { TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032), TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1), TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc) }, { 0x00, 0x00, 0x00 }, { 0x0040, 0x0200, 0x0200 }, { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff }, { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 }, }; /** * sde_encoder_phys_wb_is_master - report wb always as master encoder */ Loading Loading @@ -153,107 +135,6 @@ static void sde_encoder_phys_wb_set_qos_remap( sde_vbif_set_qos_remap(phys_enc->sde_kms, &qos_params); } /** * sde_encoder_phys_setup_cdm - setup chroma down block * @phys_enc: Pointer to physical encoder * @fb: Pointer to output framebuffer * @format: Output format */ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc, struct drm_framebuffer *fb, const struct sde_format *format, struct sde_rect *wb_roi) { struct sde_hw_cdm *hw_cdm; struct sde_hw_cdm_cfg *cdm_cfg; int ret; if (!phys_enc || !format) return; cdm_cfg = &phys_enc->cdm_cfg; hw_cdm = phys_enc->hw_cdm; if (!hw_cdm) return; if (!SDE_FORMAT_IS_YUV(format)) { SDE_DEBUG("[cdm_disable fmt:%x]\n", format->base.pixel_format); if (hw_cdm && hw_cdm->ops.disable) hw_cdm->ops.disable(hw_cdm); return; } memset(cdm_cfg, 0, sizeof(struct sde_hw_cdm_cfg)); if (!wb_roi) return; cdm_cfg->output_width = wb_roi->w; cdm_cfg->output_height = wb_roi->h; cdm_cfg->output_fmt = format; cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB; cdm_cfg->output_bit_depth = SDE_FORMAT_IS_DX(format) ? CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT; /* enable 10 bit logic */ switch (cdm_cfg->output_fmt->chroma_sample) { case SDE_CHROMA_RGB: cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; case SDE_CHROMA_H2V1: cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; case SDE_CHROMA_420: cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE; break; case SDE_CHROMA_H1V2: default: SDE_ERROR("unsupported chroma sampling type\n"); cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; break; } SDE_DEBUG("[cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n", 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 && hw_cdm->ops.setup_csc_data) { ret = hw_cdm->ops.setup_csc_data(hw_cdm, &sde_encoder_phys_wb_rgb2yuv_601l); if (ret < 0) { SDE_ERROR("failed to setup CSC %d\n", ret); return; } } if (hw_cdm && hw_cdm->ops.setup_cdwn) { ret = hw_cdm->ops.setup_cdwn(hw_cdm, cdm_cfg); if (ret < 0) { SDE_ERROR("failed to setup CDM %d\n", ret); return; } } if (hw_cdm && hw_cdm->ops.enable) { ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg); if (ret < 0) { SDE_ERROR("failed to enable CDM %d\n", ret); return; } } } /** * sde_encoder_phys_wb_setup_fb - setup output framebuffer * @phys_enc: Pointer to physical encoder Loading Loading @@ -831,7 +712,8 @@ static void sde_encoder_phys_wb_setup( sde_encoder_phys_wb_set_qos_remap(phys_enc); sde_encoder_phys_setup_cdm(phys_enc, fb, wb_enc->wb_fmt, wb_roi); sde_encoder_phys_setup_cdm(phys_enc, wb_enc->wb_fmt, CDM_CDWN_OUTPUT_WB, wb_roi); sde_encoder_phys_wb_setup_fb(phys_enc, fb, wb_roi); Loading
drivers/gpu/drm/msm/sde/sde_hw_cdm.c +2 −2 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, 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 @@ -230,7 +230,7 @@ int sde_hw_cdm_enable(struct sde_hw_cdm *ctx, return -EINVAL; if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) { if (fmt->chroma_sample != SDE_CHROMA_H1V2) if (fmt->chroma_sample == SDE_CHROMA_H1V2) return -EINVAL; /*unsupported format */ opmode = BIT(0); opmode |= (fmt->chroma_sample << 1); Loading