diff --git a/msm/dp/dp_ctrl.c b/msm/dp/dp_ctrl.c index 2c6b6a1c..58f14510 100644 --- a/msm/dp/dp_ctrl.c +++ b/msm/dp/dp_ctrl.c @@ -1126,7 +1126,7 @@ static void dp_ctrl_mst_calculate_rg(struct dp_ctrl_private *ctrl, lclk = drm_dp_bw_code_to_link_rate(ctrl->link->link_params.bw_code); if (panel->pinfo.comp_info.enabled) - bpp = DSC_BPP(panel->pinfo.comp_info.dsc_info.config); + bpp = panel->pinfo.comp_info.tgt_bpp; /* min_slot_cnt */ numerator = pclk * bpp * 64 * 1000; diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index b5f52b2e..cb2c74f1 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -1220,6 +1220,15 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp->dp_display.max_pclk_khz = min(dp->parser->max_pclk_khz, dp->debug->max_pclk_khz); + if (!dp->debug->sim_mode && !dp->no_aux_switch && !dp->parser->gpio_aux_switch + && dp->aux_switch_node) { + rc = dp->aux->aux_switch(dp->aux, true, dp->hpd->orientation); + if (rc) { + mutex_unlock(&dp->session_lock); + return rc; + } + } + /* * If dp video session is not restored from a previous session teardown * by userspace, ensure the host_init is executed, in such a scenario, diff --git a/msm/dp/dp_hdcp2p2.c b/msm/dp/dp_hdcp2p2.c index 4e2531eb..fed3e7fa 100644 --- a/msm/dp/dp_hdcp2p2.c +++ b/msm/dp/dp_hdcp2p2.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -871,7 +872,7 @@ static int dp_hdcp2p2_main(void *data) enum hdcp_transport_wakeup_cmd cmd; while (1) { - wait_event(ctrl->wait_q, + wait_event_idle(ctrl->wait_q, !kfifo_is_empty(&ctrl->cmd_q) || kthread_should_stop() || kthread_should_park()); diff --git a/msm/dp/dp_mst_drm.c b/msm/dp/dp_mst_drm.c index 477b5f5d..155008db 100644 --- a/msm/dp/dp_mst_drm.c +++ b/msm/dp/dp_mst_drm.c @@ -1204,7 +1204,8 @@ static int dp_mst_connector_atomic_check(struct drm_connector *connector, bridge->num_slots); } - if (drm_atomic_crtc_needs_modeset(crtc_state)) { + /* do not attempt to release vcpi slots if crtc state is enable */ + if (drm_atomic_crtc_needs_modeset(crtc_state) && !crtc_state->enable) { if (WARN_ON(!old_conn_state->best_encoder)) { rc = -EINVAL; goto end; diff --git a/msm/dp/dp_panel.c b/msm/dp/dp_panel.c index b9862f89..7531f749 100644 --- a/msm/dp/dp_panel.c +++ b/msm/dp/dp_panel.c @@ -388,7 +388,7 @@ static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in, tu->orig_lwidth = in->hactive; tu->hbp_relative_to_pclk_fp = drm_fixp_from_fraction(in->hporch, 1); tu->orig_hbp = in->hporch; - tu->rb2 = (in->hporch <= 80) ? 1 : 0; + tu->rb2 = (in->hporch < 160) ? 1 : 0; if (tu->pixelEnc == 420) { temp1_fp = drm_fixp_from_fraction(2, 1); @@ -419,6 +419,8 @@ static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in, if (!in->dsc_en) goto fec_check; + tu->bpp = 24; // hardcode to 24 if DSC is enabled. + temp1_fp = drm_fixp_from_fraction(in->compress_ratio, 100); temp2_fp = drm_fixp_from_fraction(in->bpp, 1); temp3_fp = drm_fixp_div(temp2_fp, temp1_fp); @@ -2840,7 +2842,8 @@ static void dp_panel_config_sdp(struct dp_panel *dp_panel, panel = container_of(dp_panel, struct dp_panel_private, dp_panel); panel->catalog->stream_id = dp_panel->stream_id; - panel->catalog->config_sdp(panel->catalog, en); + if (panel->panel_on) + panel->catalog->config_sdp(panel->catalog, en); } static int dp_panel_hw_cfg(struct dp_panel *dp_panel, bool enable) diff --git a/msm/dsi/dsi_ctrl_hw_cmn.c b/msm/dsi/dsi_ctrl_hw_cmn.c index a0afc9b7..5fcaed1b 100644 --- a/msm/dsi/dsi_ctrl_hw_cmn.c +++ b/msm/dsi/dsi_ctrl_hw_cmn.c @@ -1170,11 +1170,12 @@ void dsi_ctrl_hw_cmn_clear_interrupt_status(struct dsi_ctrl_hw *ctrl, u32 ints) reg |= BIT(30); /* - * Do not clear error status. - * It will be cleared as part of - * error handler function. + * Do not clear error status. It will be cleared as part of error handler function. + * Do not clear dynamic refresh done status. It will be cleared as part of + * wait4dynamic_refresh_done() function. */ - reg &= ~BIT(24); + reg &= ~(BIT(24) | BIT(28)); + DSI_W32(ctrl, DSI_INT_CTRL, reg); DSI_CTRL_HW_DBG(ctrl, "Clear interrupts, ints = 0x%x, INT_CTRL=0x%x\n", diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 33a2f508..a1d5e05b 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -192,7 +192,8 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge) return; } - atomic_set(&c_bridge->display->panel->esd_recovery_pending, 0); + if (bridge->encoder->crtc->state->active_changed) + atomic_set(&c_bridge->display->panel->esd_recovery_pending, 0); /* By this point mode should have been validated through mode_fixup */ rc = dsi_display_set_mode(c_bridge->display, diff --git a/msm/dsi/dsi_pll_4nm.c b/msm/dsi/dsi_pll_4nm.c index 80a94f2b..22155892 100644 --- a/msm/dsi/dsi_pll_4nm.c +++ b/msm/dsi/dsi_pll_4nm.c @@ -1481,7 +1481,8 @@ int dsi_pll_4nm_configure(void *pll, bool commit) if (rsc->slave) dsi_pll_enable_pll_bias(rsc->slave); - dsi_pll_init_val(rsc); + if (commit) + dsi_pll_init_val(rsc); rc = dsi_pll_4nm_set_byteclk_div(rsc, commit); diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 22ee4e1f..20f25686 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -1630,6 +1630,23 @@ static int _sde_connector_set_prop_out_fb(struct drm_connector *connector, return rc; } +static struct drm_encoder * +sde_connector_best_encoder(struct drm_connector *connector) +{ + struct sde_connector *c_conn = to_sde_connector(connector); + + if (!connector) { + SDE_ERROR("invalid connector\n"); + return NULL; + } + + /* + * This is true for now, revisit this code when multiple encoders are + * supported. + */ + return c_conn->encoder; +} + static int _sde_connector_set_prop_retire_fence(struct drm_connector *connector, struct drm_connector_state *state, uint64_t val) @@ -1665,9 +1682,13 @@ static int _sde_connector_set_prop_retire_fence(struct drm_connector *connector, */ offset++; - /* get hw_ctl for a wb connector */ - if (c_conn->connector_type == DRM_MODE_CONNECTOR_VIRTUAL) - hw_ctl = sde_encoder_get_hw_ctl(c_conn); + /* get hw_ctl for a wb connector not in cwb mode */ + if (c_conn->connector_type == DRM_MODE_CONNECTOR_VIRTUAL) { + struct drm_encoder *drm_enc = sde_connector_best_encoder(connector); + + if (drm_enc && !sde_encoder_in_clone_mode(drm_enc)) + hw_ctl = sde_encoder_get_hw_ctl(c_conn); + } rc = sde_fence_create(c_conn->retire_fence, &fence_user_fd, offset, hw_ctl); @@ -2645,23 +2666,6 @@ sde_connector_mode_valid(struct drm_connector *connector, return MODE_OK; } -static struct drm_encoder * -sde_connector_best_encoder(struct drm_connector *connector) -{ - struct sde_connector *c_conn = to_sde_connector(connector); - - if (!connector) { - SDE_ERROR("invalid connector\n"); - return NULL; - } - - /* - * This is true for now, revisit this code when multiple encoders are - * supported. - */ - return c_conn->encoder; -} - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) static struct drm_encoder * sde_connector_atomic_best_encoder(struct drm_connector *connector, diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index d824a443..30b5a6e5 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -3707,7 +3707,7 @@ static struct sde_hw_ctl *_sde_crtc_get_hw_ctl(struct drm_crtc *drm_crtc) struct sde_crtc *sde_crtc = to_sde_crtc(drm_crtc); if (!sde_crtc || !sde_crtc->mixers[0].hw_ctl) { - DRM_ERROR("invalid crtc params %d\n", !sde_crtc); + SDE_DEBUG("invalid crtc params %d\n", !sde_crtc); return NULL; } @@ -3724,7 +3724,6 @@ static struct dma_fence *_sde_plane_get_input_hw_fence(struct drm_plane *plane) struct dma_fence *input_hw_fence = NULL; struct dma_fence_array *array = NULL; struct dma_fence *spec_fence = NULL; - bool spec_hw_fence = true; int i; if (!plane || !plane->state) { @@ -3740,6 +3739,8 @@ static struct dma_fence *_sde_plane_get_input_hw_fence(struct drm_plane *plane) fence = (struct dma_fence *)pstate->input_fence; if (test_bit(SPEC_FENCE_FLAG_FENCE_ARRAY, &fence->flags)) { + bool spec_hw_fence = false; + array = container_of(fence, struct dma_fence_array, base); if (IS_ERR_OR_NULL(array)) goto exit; @@ -3750,9 +3751,18 @@ static struct dma_fence *_sde_plane_get_input_hw_fence(struct drm_plane *plane) for (i = 0; i < array->num_fences; i++) { spec_fence = array->fences[i]; - if (IS_ERR_OR_NULL(spec_fence) || - !(test_bit(MSM_HW_FENCE_FLAG_ENABLED_BIT, - &spec_fence->flags))) { + + if (!IS_ERR_OR_NULL(spec_fence) && + test_bit(MSM_HW_FENCE_FLAG_ENABLED_BIT, + &spec_fence->flags)) { + spec_hw_fence = true; + } else { + /* + * all child-fences of the spec fence must be hw-fences for + * this fence to be considered hw-fence. Otherwise just + * fail here to set the hw-fences and driver will use + * sw-fences instead. + */ spec_hw_fence = false; break; } diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index e72a07ec..acb746a9 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -3844,16 +3844,10 @@ static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc, ctl->ops.update_bitmask) { /* perform peripheral flush on every frame update for dp dsc */ if (phys->comp_type == MSM_DISPLAY_COMPRESSION_DSC && - phys->comp_ratio && c_conn->ops.update_pps) { - c_conn->ops.update_pps(phys->connector, NULL, - c_conn->display); - ctl->ops.update_bitmask(ctl, SDE_HW_FLUSH_PERIPH, - phys->hw_intf->idx, 1); - } + phys->comp_ratio && c_conn->ops.update_pps) + c_conn->ops.update_pps(phys->connector, NULL, c_conn->display); - if (sde_enc->dynamic_hdr_updated) - ctl->ops.update_bitmask(ctl, SDE_HW_FLUSH_PERIPH, - phys->hw_intf->idx, 1); + ctl->ops.update_bitmask(ctl, SDE_HW_FLUSH_PERIPH, phys->hw_intf->idx, 1); } if ((extra_flush && extra_flush->pending_flush_mask) diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index 915d7cb5..9591b97b 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -1223,9 +1223,7 @@ static void _sde_encoder_phys_cmd_pingpong_config( static void sde_encoder_phys_cmd_enable_helper( struct sde_encoder_phys *phys_enc) { - struct sde_encoder_virt *sde_enc; struct sde_hw_intf *hw_intf; - u32 qsync_mode; if (!phys_enc || !phys_enc->hw_ctl || !phys_enc->hw_pp || !phys_enc->hw_intf) { @@ -1247,19 +1245,6 @@ static void sde_encoder_phys_cmd_enable_helper( hw_intf->ops.enable_wide_bus(hw_intf, sde_encoder_is_widebus_enabled(phys_enc->parent)); - /* - * Override internal rd_ptr value when coming out of IPC. - * This is required on QSYNC panel with low refresh rate to - * avoid out of sync frame trigger as panel rd_ptr was still - * incrementing while MDP was power collapsed. - */ - sde_enc = to_sde_encoder_virt(phys_enc->parent); - if (sde_enc->idle_pc_restore) { - qsync_mode = sde_connector_get_qsync_mode(phys_enc->connector); - if (qsync_mode) - sde_encoder_override_tearcheck_rd_ptr(phys_enc); - } - /* * For pp-split, skip setting the flush bit for the slave intf, since * both intfs use same ctl and HW will only flush the master. diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index 6c799f21..ba4c46ae 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -963,7 +963,6 @@ static void sde_encoder_phys_vid_update_txq(struct sde_encoder_phys *phys_enc) if (!sde_enc) return; - SDE_EVT32(DRMID(phys_enc->parent)); sde_encoder_helper_update_out_fence_txq(sde_enc, true); } diff --git a/msm/sde/sde_fence.c b/msm/sde/sde_fence.c index 4bc74720..d2931a87 100644 --- a/msm/sde/sde_fence.c +++ b/msm/sde/sde_fence.c @@ -301,10 +301,26 @@ int sde_fence_register_hw_fences_wait(struct sde_hw_ctl *hw_ctl, struct dma_fenc dma_fence_get(array->fences[j]); fence_list[fence_list_index++] = array->fences[j]; } + + if (array->num_fences) /* print the first fence from array */ + SDE_EVT32(ctl_id, num_fences, array->num_fences, i, + SDE_EVTLOG_H32(array->fences[0]->context), + SDE_EVTLOG_L32(array->fences[0]->context), + SDE_EVTLOG_H32(array->fences[0]->seqno), + SDE_EVTLOG_L32(array->fences[0]->seqno)); + else + SDE_EVT32(ctl_id, num_fences, array->num_fences, i, + SDE_EVTLOG_ERROR); + /* remove refcount on parent */ dma_fence_put(fences[i]); } else { fence_list[fence_list_index++] = fences[i]; + + SDE_EVT32(ctl_id, num_fences, i, SDE_EVTLOG_H32(fences[i]->context), + SDE_EVTLOG_L32(fences[i]->context), + SDE_EVTLOG_H32(fences[i]->seqno), + SDE_EVTLOG_L32(fences[i]->seqno)); } } @@ -322,8 +338,17 @@ int sde_fence_register_hw_fences_wait(struct sde_hw_ctl *hw_ctl, struct dma_fenc num_hw_fences = 1; } else { + struct dma_fence_array *tmp_array; + hw_fences = fences; num_hw_fences = num_fences; + tmp_array = dma_fence_is_array(fences[0]) ? + container_of(fences[0], struct dma_fence_array, base) : + NULL; + SDE_EVT32(ctl_id, num_hw_fences, SDE_EVTLOG_H32(fences[0]->context), + SDE_EVTLOG_L32(fences[0]->context), SDE_EVTLOG_H32(fences[0]->seqno), + SDE_EVTLOG_L32(fences[0]->seqno), fences[0]->flags, + tmp_array ? tmp_array->num_fences : SDE_EVTLOG_FUNC_CASE2); } /* register for wait */ @@ -481,6 +506,8 @@ int sde_fence_update_hw_fences_txq(struct sde_fence_context *ctx, bool vid_mode, } /* update hw-fence tx queue */ + SDE_EVT32(ctl_id, SDE_EVTLOG_H32(fc->hwfence_index), + SDE_EVTLOG_L32(fc->hwfence_index)); ret = msm_hw_fence_update_txq(data->hw_fence_handle, fc->hwfence_index, 0, 0); if (ret) { SDE_ERROR("fail txq update index:%llu fctx:%llu seqno:%llu client:%d\n", diff --git a/msm/sde/sde_hw_intf.c b/msm/sde/sde_hw_intf.c index 3c9e9f98..23c8299f 100644 --- a/msm/sde/sde_hw_intf.c +++ b/msm/sde/sde_hw_intf.c @@ -679,8 +679,6 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf, * less than 2^16 vsync clk cycles. */ spin_lock(&tearcheck_spinlock); - SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, - (te->start_pos + te->sync_threshold_start + 1)); SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg); wmb(); /* disable vsync counter before updating single buffer registers */ SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_HEIGHT, te->sync_cfg_height); @@ -693,6 +691,10 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf, te->sync_threshold_start)); cfg |= BIT(19); /* VSYNC_COUNTER_EN */ SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg); + wmb(); /* ensure vsync_counter_en is written */ + + SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, + (te->start_pos + te->sync_threshold_start + 1)); spin_unlock(&tearcheck_spinlock); return 0; diff --git a/msm/sde/sde_hw_rc.c b/msm/sde/sde_hw_rc.c index 470d4a03..4b02a850 100644 --- a/msm/sde/sde_hw_rc.c +++ b/msm/sde/sde_hw_rc.c @@ -333,14 +333,15 @@ static int _sde_hw_rc_get_ajusted_roi( if (pu_roi->w == 0 && pu_roi->h == 0) { rc_roi->x = pu_roi->x; rc_roi->y = pu_roi->y; - rc_roi->w = hw_cfg->displayh; - rc_roi->h = hw_cfg->displayv; + rc_roi->w = hw_cfg->panel_width; + rc_roi->h = hw_cfg->panel_height; } else { memcpy(rc_roi, pu_roi, sizeof(struct sde_rect)); } - SDE_DEBUG("displayh:%u, displayv:%u\n", hw_cfg->displayh, - hw_cfg->displayv); + SDE_EVT32(hw_cfg->displayh, hw_cfg->displayv, hw_cfg->panel_width, hw_cfg->panel_height); + SDE_DEBUG("displayh:%u, displayv:%u, panel_w:%u, panel_h:%u\n", hw_cfg->displayh, + hw_cfg->displayv, hw_cfg->panel_width, hw_cfg->panel_height); SDE_DEBUG("pu_roi x:%u, y:%u, w:%u, h:%u\n", pu_roi->x, pu_roi->y, pu_roi->w, pu_roi->h); SDE_DEBUG("rc_roi x:%u, y:%u, w:%u, h:%u\n", rc_roi->x, rc_roi->y, @@ -925,6 +926,7 @@ int sde_hw_rc_setup_mask(struct sde_hw_dspp *hw_dspp, void *cfg) struct msm_roi_list *last_roi_list; u32 merge_mode = 0; bool roi_programmed = false; + u64 mask_w = 0, mask_h = 0, panel_w = 0, panel_h = 0; if (!hw_dspp || !hw_cfg) { SDE_ERROR("invalid arguments\n"); @@ -957,6 +959,19 @@ int sde_hw_rc_setup_mask(struct sde_hw_dspp *hw_dspp, void *cfg) last_roi_list = RC_STATE(hw_dspp).last_roi_list; roi_programmed = RC_STATE(hw_dspp).roi_programmed; + mask_w = rc_mask_cfg->width; + mask_h = rc_mask_cfg->height; + panel_w = hw_cfg->panel_width; + panel_h = hw_cfg->panel_height; + + if ((panel_w != mask_w || panel_h != mask_h)) { + SDE_ERROR("RC-%d mask: w %d h %d panel: w %d h %d mismatch\n", + RC_IDX(hw_dspp), mask_w, mask_h, panel_w, panel_h); + SDE_EVT32(1); + _sde_hw_rc_reg_write(hw_dspp, SDE_HW_RC_REG1, 0); + return -EINVAL; + } + if (!roi_programmed) { SDE_DEBUG("full frame update\n"); memset(&merged_roi, 0, sizeof(struct sde_rect)); diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 09f90d6f..7c1d1043 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -1100,7 +1100,7 @@ static void _sde_plane_setup_pixel_ext(struct sde_plane *psde, } } -static inline void _sde_plane_setup_csc(struct sde_plane *psde) +static inline void _sde_plane_setup_csc(struct sde_plane *psde, struct sde_plane_state *pstate) { static const struct sde_csc_cfg sde_csc_YUV2RGB_601L = { { @@ -1131,23 +1131,23 @@ static inline void _sde_plane_setup_csc(struct sde_plane *psde) { 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,}, }; - if (!psde) { + if (!psde || !pstate) { SDE_ERROR("invalid plane\n"); return; } /* revert to kernel default if override not available */ - if (psde->csc_usr_ptr) - psde->csc_ptr = psde->csc_usr_ptr; + if (pstate->csc_usr_ptr) + pstate->csc_ptr = pstate->csc_usr_ptr; else if (BIT(SDE_SSPP_CSC_10BIT) & psde->features) - psde->csc_ptr = (struct sde_csc_cfg *)&sde_csc10_YUV2RGB_601L; + pstate->csc_ptr = (struct sde_csc_cfg *)&sde_csc10_YUV2RGB_601L; else - psde->csc_ptr = (struct sde_csc_cfg *)&sde_csc_YUV2RGB_601L; + pstate->csc_ptr = (struct sde_csc_cfg *)&sde_csc_YUV2RGB_601L; SDE_DEBUG_PLANE(psde, "using 0x%X 0x%X 0x%X...\n", - psde->csc_ptr->csc_mv[0], - psde->csc_ptr->csc_mv[1], - psde->csc_ptr->csc_mv[2]); + pstate->csc_ptr->csc_mv[0], + pstate->csc_ptr->csc_mv[1], + pstate->csc_ptr->csc_mv[2]); } static void sde_color_process_plane_setup(struct drm_plane *plane) @@ -2776,8 +2776,8 @@ void sde_plane_flush(struct drm_plane *plane) else if (psde->color_fill & SDE_PLANE_COLOR_FILL_FLAG) /* force 100% alpha */ _sde_plane_color_fill(psde, psde->color_fill, 0xFF); - else if (psde->pipe_hw && psde->csc_ptr && psde->pipe_hw->ops.setup_csc) - psde->pipe_hw->ops.setup_csc(psde->pipe_hw, psde->csc_ptr); + else if (psde->pipe_hw && pstate->csc_ptr && psde->pipe_hw->ops.setup_csc) + psde->pipe_hw->ops.setup_csc(psde->pipe_hw, pstate->csc_ptr); /* flag h/w flush complete */ if (plane->state) @@ -3200,9 +3200,9 @@ static void _sde_plane_update_format_and_rects(struct sde_plane *psde, /* update csc */ if (SDE_FORMAT_IS_YUV(fmt)) - _sde_plane_setup_csc(psde); + _sde_plane_setup_csc(psde, pstate); else - psde->csc_ptr = 0; + pstate->csc_ptr = 0; if (psde->pipe_hw->ops.setup_inverse_pma) { uint32_t pma_mode = 0; @@ -3216,7 +3216,7 @@ static void _sde_plane_update_format_and_rects(struct sde_plane *psde, if (psde->pipe_hw->ops.setup_dgm_csc) psde->pipe_hw->ops.setup_dgm_csc(psde->pipe_hw, - pstate->multirect_index, psde->csc_usr_ptr); + pstate->multirect_index, pstate->csc_usr_ptr); if (psde->pipe_hw->ops.set_ubwc_stats_roi) { if (SDE_FORMAT_IS_UBWC(fmt) && !SDE_FORMAT_IS_YUV(fmt)) @@ -3998,17 +3998,17 @@ static void _sde_plane_install_properties(struct drm_plane *plane, } static inline void _sde_plane_set_csc_v1(struct sde_plane *psde, - void __user *usr_ptr) + void __user *usr_ptr, struct sde_plane_state *pstate) { struct sde_drm_csc_v1 csc_v1; int i; - if (!psde) { + if (!psde || !pstate) { SDE_ERROR("invalid plane\n"); return; } - psde->csc_usr_ptr = NULL; + pstate->csc_usr_ptr = NULL; if (!usr_ptr) { SDE_DEBUG_PLANE(psde, "csc data removed\n"); return; @@ -4021,16 +4021,16 @@ static inline void _sde_plane_set_csc_v1(struct sde_plane *psde, /* populate from user space */ for (i = 0; i < SDE_CSC_MATRIX_COEFF_SIZE; ++i) - psde->csc_cfg.csc_mv[i] = csc_v1.ctm_coeff[i] >> 16; + pstate->csc_cfg.csc_mv[i] = csc_v1.ctm_coeff[i] >> 16; for (i = 0; i < SDE_CSC_BIAS_SIZE; ++i) { - psde->csc_cfg.csc_pre_bv[i] = csc_v1.pre_bias[i]; - psde->csc_cfg.csc_post_bv[i] = csc_v1.post_bias[i]; + pstate->csc_cfg.csc_pre_bv[i] = csc_v1.pre_bias[i]; + pstate->csc_cfg.csc_post_bv[i] = csc_v1.post_bias[i]; } for (i = 0; i < SDE_CSC_CLAMP_SIZE; ++i) { - psde->csc_cfg.csc_pre_lv[i] = csc_v1.pre_clamp[i]; - psde->csc_cfg.csc_post_lv[i] = csc_v1.post_clamp[i]; + pstate->csc_cfg.csc_pre_lv[i] = csc_v1.pre_clamp[i]; + pstate->csc_cfg.csc_post_lv[i] = csc_v1.post_clamp[i]; } - psde->csc_usr_ptr = &psde->csc_cfg; + pstate->csc_usr_ptr = &pstate->csc_cfg; } static inline void _sde_plane_set_scaler_v1(struct sde_plane *psde, @@ -4267,7 +4267,7 @@ static int sde_plane_atomic_set_property(struct drm_plane *plane, break; case PLANE_PROP_CSC_V1: case PLANE_PROP_CSC_DMA_V1: - _sde_plane_set_csc_v1(psde, (void __user *)val); + _sde_plane_set_csc_v1(psde, (void __user *)val, pstate); break; case PLANE_PROP_SCALER_V1: _sde_plane_set_scaler_v1(psde, pstate, diff --git a/msm/sde/sde_plane.h b/msm/sde/sde_plane.h index 7eab4726..e203bd0e 100644 --- a/msm/sde/sde_plane.h +++ b/msm/sde/sde_plane.h @@ -75,10 +75,6 @@ struct sde_plane { bool revalidate; bool xin_halt_forced_clk; - struct sde_csc_cfg csc_cfg; - struct sde_csc_cfg *csc_usr_ptr; - struct sde_csc_cfg *csc_ptr; - uint32_t cached_lut_flag; struct sde_hw_scaler3_cfg scaler3_cfg; struct sde_hw_pixel_ext pixel_ext; @@ -164,6 +160,9 @@ enum sde_plane_sclcheck_state { * @ubwc_stats_roi: cached roi for ubwc stats * @line_insertion_cfg: line insertion configuration * @lineinsertion_feature: panel line insertion feature + * @csc_cfg: csc configuration for pipe + * @csc_usr_ptr: valid user override configuration for csc + * @csc_ptr: default csc configuration */ struct sde_plane_state { struct drm_plane_state base; @@ -202,6 +201,10 @@ struct sde_plane_state { struct sde_drm_ubwc_stats_roi ubwc_stats_roi; struct sde_hw_pipe_line_insertion_cfg line_insertion_cfg; bool lineinsertion_feature; + + struct sde_csc_cfg csc_cfg; + struct sde_csc_cfg *csc_usr_ptr; + struct sde_csc_cfg *csc_ptr; }; /** diff --git a/msm/sde_dbg.h b/msm/sde_dbg.h index a4d9591a..4075836c 100644 --- a/msm/sde_dbg.h +++ b/msm/sde_dbg.h @@ -31,6 +31,9 @@ #define SDE_EVTLOG_FATAL 0xbad #define SDE_EVTLOG_ERROR 0xebad +#define SDE_EVTLOG_H32(val) (val >> 32) +#define SDE_EVTLOG_L32(val) (val & 0xffffffff) + /* flags to enable the HW block dumping */ #define SDE_DBG_SDE BIT(0) #define SDE_DBG_RSC BIT(1) diff --git a/msm/sde_hdcp_2x.c b/msm/sde_hdcp_2x.c index b346b871..25906300 100644 --- a/msm/sde_hdcp_2x.c +++ b/msm/sde_hdcp_2x.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -970,7 +971,7 @@ static int sde_hdcp_2x_main(void *data) enum sde_hdcp_2x_wakeup_cmd cmd; while (1) { - wait_event(hdcp->wait_q, + wait_event_idle(hdcp->wait_q, !kfifo_is_empty(&hdcp->cmd_q) || kthread_should_stop() || kthread_should_park());