diff options
author | Wilson Sung <wilsonsung@google.com> | 2022-03-24 16:13:56 +0800 |
---|---|---|
committer | Wilson Sung <wilsonsung@google.com> | 2022-03-24 16:13:56 +0800 |
commit | 71f924dada382392139719de510ec237eff8867f (patch) | |
tree | 49a0a0836b29ced789b153ae126ef21719395675 | |
parent | 2138ca0795500251b7590cb9d6f41d46da451b84 (diff) | |
parent | ce33c52e42d2bd6214c3daf06a7510d08be33c15 (diff) | |
download | display-drivers-71f924dada382392139719de510ec237eff8867f.tar.gz |
Merge branch LA.UM.9.12.C10.11.00.00.840.265 into qcom-msm-4.19-7250
Change-Id: Ibe92346b998ae84a67160ee85f4968c812a416c2
-rw-r--r-- | msm/dsi/dsi_phy.c | 3 | ||||
-rw-r--r-- | msm/dsi/dsi_phy.h | 3 | ||||
-rw-r--r-- | msm/dsi/dsi_phy_hw.h | 3 | ||||
-rw-r--r-- | msm/dsi/dsi_phy_hw_v4_0.c | 40 | ||||
-rw-r--r-- | msm/sde/sde_crtc.c | 2 | ||||
-rw-r--r-- | msm/sde/sde_encoder.c | 41 | ||||
-rw-r--r-- | msm/sde/sde_encoder.h | 9 | ||||
-rw-r--r-- | msm/sde/sde_encoder_phys_vid.c | 41 | ||||
-rw-r--r-- | msm/sde/sde_kms.c | 8 | ||||
-rw-r--r-- | msm/sde/sde_kms.h | 6 |
10 files changed, 141 insertions, 15 deletions
diff --git a/msm/dsi/dsi_phy.c b/msm/dsi/dsi_phy.c index 4115138b..2f116bfb 100644 --- a/msm/dsi/dsi_phy.c +++ b/msm/dsi/dsi_phy.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/of_device.h> @@ -880,8 +881,8 @@ int dsi_phy_enable(struct msm_dsi_phy *phy, memcpy(&phy->mode, &config->video_timing, sizeof(phy->mode)); memcpy(&phy->cfg.lane_map, &config->lane_map, sizeof(config->lane_map)); - phy->data_lanes = config->common_config.data_lanes; phy->dst_format = config->common_config.dst_format; + phy->cfg.data_lanes = config->common_config.data_lanes; phy->cfg.pll_source = pll_source; phy->cfg.bit_clk_rate_hz = config->bit_clk_rate_hz; diff --git a/msm/dsi/dsi_phy.h b/msm/dsi/dsi_phy.h index 6643a940..f621a15c 100644 --- a/msm/dsi/dsi_phy.h +++ b/msm/dsi/dsi_phy.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _DSI_PHY_H_ @@ -68,7 +69,6 @@ enum phy_ulps_return_type { * @power_state: True if PHY is powered on. * @dsi_phy_state: PHY state information. * @mode: Current mode. - * @data_lanes: Number of data lanes used. * @dst_format: Destination format. * @allow_phy_power_off: True if PHY is allowed to power off when idle * @regulator_min_datarate_bps: Minimum per lane data rate to turn on regulator @@ -92,7 +92,6 @@ struct msm_dsi_phy { enum phy_engine_state dsi_phy_state; bool power_state; struct dsi_mode_info mode; - enum dsi_data_lanes data_lanes; enum dsi_pixel_format dst_format; bool allow_phy_power_off; diff --git a/msm/dsi/dsi_phy_hw.h b/msm/dsi/dsi_phy_hw.h index b550ee72..ef60301f 100644 --- a/msm/dsi/dsi_phy_hw.h +++ b/msm/dsi/dsi_phy_hw.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _DSI_PHY_HW_H_ @@ -96,6 +97,7 @@ struct dsi_phy_per_lane_cfgs { * @is_phy_timing_present: Boolean whether phy timings are defined. * @regulators: Regulator settings for lanes. * @pll_source: PLL source. + * @data_lanes: Number of data lanes used. * @lane_map: DSI logical to PHY lane mapping. * @force_clk_lane_hs:Boolean whether to force clock lane in HS mode. * @phy_type: Phy-type (Dphy/Cphy). @@ -112,6 +114,7 @@ struct dsi_phy_cfg { bool force_clk_lane_hs; enum dsi_phy_type phy_type; unsigned long bit_clk_rate_hz; + u32 data_lanes; }; struct dsi_phy_hw; diff --git a/msm/dsi/dsi_phy_hw_v4_0.c b/msm/dsi/dsi_phy_hw_v4_0.c index 220e9de5..d33eea20 100644 --- a/msm/dsi/dsi_phy_hw_v4_0.c +++ b/msm/dsi/dsi_phy_hw_v4_0.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/math64.h> @@ -203,6 +204,26 @@ void dsi_phy_hw_v4_0_commit_phy_timing(struct dsi_phy_hw *phy, } /** + * calc_cmn_lane_ctrl0() - Calculate the value to be set for + * DSIPHY_CMN_LANE_CTRL0 register. + * @cfg: Per lane configurations for timing, strength and lane + * configurations. + */ +static inline int dsi_phy_hw_calc_cmn_lane_ctrl0(struct dsi_phy_cfg *cfg) +{ + u32 cmn_lane_ctrl0 = 0; + + /* Only enable lanes that are required */ + cmn_lane_ctrl0 |= ((cfg->data_lanes & DSI_DATA_LANE_0) ? BIT(0) : 0); + cmn_lane_ctrl0 |= ((cfg->data_lanes & DSI_DATA_LANE_1) ? BIT(1) : 0); + cmn_lane_ctrl0 |= ((cfg->data_lanes & DSI_DATA_LANE_2) ? BIT(2) : 0); + cmn_lane_ctrl0 |= ((cfg->data_lanes & DSI_DATA_LANE_3) ? BIT(3) : 0); + cmn_lane_ctrl0 |= BIT(4); + + return cmn_lane_ctrl0; +} + +/** * cphy_enable() - Enable CPHY hardware * @phy: Pointer to DSI PHY hardware object. * @cfg: Per lane configurations for timing, strength and lane @@ -220,6 +241,7 @@ static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy, u32 glbl_hstx_str_ctrl_0 = 0; u32 glbl_rescode_top_ctrl = 0; u32 glbl_rescode_bot_ctrl = 0; + u32 cmn_lane_ctrl0 = 0; if (phy->version == DSI_PHY_VERSION_4_1) { glbl_rescode_top_ctrl = 0x00; @@ -271,7 +293,9 @@ static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy, /* Remove power down from all blocks */ DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f); - DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x17); + cmn_lane_ctrl0 = dsi_phy_hw_calc_cmn_lane_ctrl0(cfg); + + DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, cmn_lane_ctrl0); switch (cfg->pll_source) { case DSI_PLL_SOURCE_STANDALONE: @@ -321,6 +345,7 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, u32 glbl_hstx_str_ctrl_0 = 0; u32 glbl_rescode_top_ctrl = 0; u32 glbl_rescode_bot_ctrl = 0; + u32 cmn_lane_ctrl0 = 0; /* Alter PHY configurations if data rate less than 1.5GHZ*/ if (cfg->bit_clk_rate_hz <= 1500000000) @@ -377,7 +402,9 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, /* Remove power down from all blocks */ DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f); - DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x1F); + cmn_lane_ctrl0 = dsi_phy_hw_calc_cmn_lane_ctrl0(cfg); + + DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, cmn_lane_ctrl0); /* Select full-rate mode */ DSI_W32(phy, DSIPHY_CMN_CTRL_2, 0x40); @@ -652,8 +679,7 @@ void dsi_phy_hw_v4_0_dyn_refresh_config(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg, bool is_master) { u32 reg; - bool is_cphy = (cfg->phy_type == DSI_PHY_TYPE_CPHY) ? - true : false; + u32 cmn_lane_ctrl0 = dsi_phy_hw_calc_cmn_lane_ctrl0(cfg); if (is_master) { DSI_DYN_REF_REG_W(phy->dyn_pll_base, DSI_DYN_REFRESH_PLL_CTRL19, @@ -679,7 +705,7 @@ void dsi_phy_hw_v4_0_dyn_refresh_config(struct dsi_phy_hw *phy, cfg->timing.lane_v4[12], cfg->timing.lane_v4[13]); DSI_DYN_REF_REG_W(phy->dyn_pll_base, DSI_DYN_REFRESH_PLL_CTRL26, DSIPHY_CMN_CTRL_0, DSIPHY_CMN_LANE_CTRL0, - 0x7f, is_cphy ? 0x17 : 0x1f); + 0x7f, cmn_lane_ctrl0); } else { reg = DSI_R32(phy, DSIPHY_CMN_CLK_CFG1); @@ -714,7 +740,7 @@ void dsi_phy_hw_v4_0_dyn_refresh_config(struct dsi_phy_hw *phy, cfg->timing.lane_v4[13], 0x7f); DSI_DYN_REF_REG_W(phy->dyn_pll_base, DSI_DYN_REFRESH_PLL_CTRL9, DSIPHY_CMN_LANE_CTRL0, DSIPHY_CMN_CTRL_2, - is_cphy ? 0x17 : 0x1f, 0x40); + cmn_lane_ctrl0, 0x40); /* * fill with dummy register writes since controller will blindly * send these values to DSI PHY. @@ -723,7 +749,7 @@ void dsi_phy_hw_v4_0_dyn_refresh_config(struct dsi_phy_hw *phy, while (reg <= DSI_DYN_REFRESH_PLL_CTRL29) { DSI_DYN_REF_REG_W(phy->dyn_pll_base, reg, DSIPHY_CMN_LANE_CTRL0, DSIPHY_CMN_CTRL_0, - is_cphy ? 0x17 : 0x1f, 0x7f); + cmn_lane_ctrl0, 0x7f); reg += 0x4; } diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 46bb184a..86b38a69 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> * @@ -3194,6 +3195,7 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, if (encoder->crtc != crtc) continue; + sde_encoder_trigger_rsc_state_change(encoder); /* encoder will trigger pending mask now */ sde_encoder_trigger_kickoff_pending(encoder); } diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 691bbc22..71bbeaf7 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> * @@ -4398,6 +4399,46 @@ bool sde_encoder_check_curr_mode(struct drm_encoder *drm_enc, u32 mode) return (disp_info->curr_panel_mode == mode); } +void sde_encoder_trigger_rsc_state_change(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc = NULL; + int ret = 0; + + sde_enc = to_sde_encoder_virt(drm_enc); + + if (!sde_enc) + return; + + mutex_lock(&sde_enc->rc_lock); + /* + * In dual display case when secondary comes out of + * idle make sure RSC solver mode is disabled before + * setting CTL_PREPARE. + */ + if (!sde_enc->cur_master || + !sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE) || + sde_enc->disp_info.display_type == SDE_CONNECTOR_PRIMARY || + sde_enc->rc_state != SDE_ENC_RC_STATE_IDLE) + goto end; + + /* enable all the clks and resources */ + ret = _sde_encoder_resource_control_helper(drm_enc, true); + if (ret) { + SDE_ERROR_ENC(sde_enc, "rc in state %d\n", sde_enc->rc_state); + SDE_EVT32(DRMID(drm_enc), sde_enc->rc_state, SDE_EVTLOG_ERROR); + goto end; + } + + _sde_encoder_update_rsc_client(drm_enc, true); + + SDE_EVT32(DRMID(drm_enc), sde_enc->rc_state, SDE_ENC_RC_STATE_ON); + sde_enc->rc_state = SDE_ENC_RC_STATE_ON; + +end: + mutex_unlock(&sde_enc->rc_lock); +} + + void sde_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc; diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 48442767..ebee140d 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> * @@ -97,6 +98,12 @@ void sde_encoder_get_hw_resources(struct drm_encoder *encoder, struct drm_connector_state *conn_state); /** + * sde_encoder_trigger_rsc_state_change - rsc state change. + * @encoder: encoder pointer + */ +void sde_encoder_trigger_rsc_state_change(struct drm_encoder *drm_enc); + +/** * sde_encoder_register_vblank_callback - provide callback to encoder that * will be called on the next vblank. * @encoder: encoder pointer diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index 7708cf8f..67e6b068 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -1080,12 +1081,47 @@ exit: phys_enc->enable_state = SDE_ENC_DISABLED; } +static int sde_encoder_phys_vid_poll_for_active_region( + struct sde_encoder_phys *phys_enc) +{ + struct sde_encoder_phys_vid *vid_enc; + struct intf_timing_params *timing; + struct drm_display_mode mode; + u32 line_cnt, v_inactive, poll_time_us, trial = 0; + + if (!phys_enc || !phys_enc->hw_intf || + !phys_enc->hw_intf->ops.get_line_count) + return -EINVAL; + + vid_enc = to_sde_encoder_phys_vid(phys_enc); + timing = &vid_enc->timing_params; + mode = phys_enc->cached_mode; + + /* if programmable fetch is not enabled return early */ + if (!programmable_fetch_get_num_lines(vid_enc, timing, false)) + return 0; + + poll_time_us = DIV_ROUND_UP(1000000, mode.vrefresh) / MAX_POLL_CNT; + v_inactive = timing->v_front_porch + timing->v_back_porch + + timing->vsync_pulse_width; + + do { + usleep_range(poll_time_us, poll_time_us + 5); + line_cnt = phys_enc->hw_intf->ops.get_line_count( + phys_enc->hw_intf); + trial++; + } while ((trial < MAX_POLL_CNT) || (line_cnt < v_inactive)); + + return (trial >= MAX_POLL_CNT) ? -ETIMEDOUT : 0; +} + static void sde_encoder_phys_vid_handle_post_kickoff( struct sde_encoder_phys *phys_enc) { unsigned long lock_flags; struct sde_encoder_phys_vid *vid_enc; u32 avr_mode; + u32 ret; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); @@ -1108,6 +1144,11 @@ static void sde_encoder_phys_vid_handle_post_kickoff( 1); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); + ret = sde_encoder_phys_vid_poll_for_active_region( + phys_enc); + if (ret) + SDE_DEBUG_VIDENC(vid_enc, + "poll for active failed ret:%d\n", ret); } phys_enc->enable_state = SDE_ENC_ENABLED; } diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index d5ac13a6..2b8e9e6f 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> @@ -1099,9 +1100,10 @@ static void _sde_kms_release_splash_resource(struct sde_kms *sde_kms, /* remove the votes if all displays are done with splash */ if (!sde_kms->splash_data.num_splash_displays) { for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) - sde_power_data_bus_set_quota(&priv->phandle, i, - SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA, - SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA); + if (sde_kms->perf.sde_rsc_available) + sde_power_data_bus_set_quota(&priv->phandle, i, + SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA, + SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA); pm_runtime_put_sync(sde_kms->dev->dev); } diff --git a/msm/sde/sde_kms.h b/msm/sde/sde_kms.h index 50a4de5f..6882cdfd 100644 --- a/msm/sde/sde_kms.h +++ b/msm/sde/sde_kms.h @@ -464,7 +464,11 @@ void *sde_debugfs_get_root(struct sde_kms *sde_kms); * These functions/definitions allow for building up a 'sde_info' structure * containing one or more "key=value\n" entries. */ -#define SDE_KMS_INFO_MAX_SIZE 4096 +#if IS_ENABLED(CONFIG_DRM_LOW_MSM_MEM_FOOTPRINT) +#define SDE_KMS_INFO_MAX_SIZE (1 << 12) +#else +#define SDE_KMS_INFO_MAX_SIZE (1 << 14) +#endif /** * struct sde_kms_info - connector information structure container |