summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilson Sung <wilsonsung@google.com>2022-03-24 16:13:56 +0800
committerWilson Sung <wilsonsung@google.com>2022-03-24 16:13:56 +0800
commit71f924dada382392139719de510ec237eff8867f (patch)
tree49a0a0836b29ced789b153ae126ef21719395675
parent2138ca0795500251b7590cb9d6f41d46da451b84 (diff)
parentce33c52e42d2bd6214c3daf06a7510d08be33c15 (diff)
downloaddisplay-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.c3
-rw-r--r--msm/dsi/dsi_phy.h3
-rw-r--r--msm/dsi/dsi_phy_hw.h3
-rw-r--r--msm/dsi/dsi_phy_hw_v4_0.c40
-rw-r--r--msm/sde/sde_crtc.c2
-rw-r--r--msm/sde/sde_encoder.c41
-rw-r--r--msm/sde/sde_encoder.h9
-rw-r--r--msm/sde/sde_encoder_phys_vid.c41
-rw-r--r--msm/sde/sde_kms.c8
-rw-r--r--msm/sde/sde_kms.h6
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