Merge "disp: msm: sde: enable EPT feature for pineapple target"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
76f59dbdd1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (C) 2013 Red Hat
|
* Copyright (C) 2013 Red Hat
|
||||||
* Author: Rob Clark <robdclark@gmail.com>
|
* Author: Rob Clark <robdclark@gmail.com>
|
||||||
@@ -247,6 +247,7 @@ enum msm_mdp_conn_property {
|
|||||||
CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE,
|
CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE,
|
||||||
CONNECTOR_PROP_SET_PANEL_MODE,
|
CONNECTOR_PROP_SET_PANEL_MODE,
|
||||||
CONNECTOR_PROP_AVR_STEP,
|
CONNECTOR_PROP_AVR_STEP,
|
||||||
|
CONNECTOR_PROP_EPT,
|
||||||
CONNECTOR_PROP_CACHE_STATE,
|
CONNECTOR_PROP_CACHE_STATE,
|
||||||
CONNECTOR_PROP_DSC_MODE,
|
CONNECTOR_PROP_DSC_MODE,
|
||||||
CONNECTOR_PROP_WB_USAGE_TYPE,
|
CONNECTOR_PROP_WB_USAGE_TYPE,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -3175,6 +3175,10 @@ static int _sde_connector_install_properties(struct drm_device *dev,
|
|||||||
"qsync_mode", 0, 0, e_qsync_mode,
|
"qsync_mode", 0, 0, e_qsync_mode,
|
||||||
ARRAY_SIZE(e_qsync_mode), 0,
|
ARRAY_SIZE(e_qsync_mode), 0,
|
||||||
CONNECTOR_PROP_QSYNC_MODE);
|
CONNECTOR_PROP_QSYNC_MODE);
|
||||||
|
if (test_bit(SDE_FEATURE_EPT, sde_kms->catalog->features))
|
||||||
|
msm_property_install_range(&c_conn->property_info,
|
||||||
|
"EPT", 0x0, 0, U64_MAX, 0,
|
||||||
|
CONNECTOR_PROP_EPT);
|
||||||
if (test_bit(SDE_FEATURE_AVR_STEP, sde_kms->catalog->features))
|
if (test_bit(SDE_FEATURE_AVR_STEP, sde_kms->catalog->features))
|
||||||
msm_property_install_range(&c_conn->property_info,
|
msm_property_install_range(&c_conn->property_info,
|
||||||
"avr_step", 0x0, 0, U32_MAX, 0,
|
"avr_step", 0x0, 0, U32_MAX, 0,
|
||||||
|
@@ -1241,7 +1241,7 @@ static int _sde_encoder_atomic_check_qsync(struct sde_connector *sde_conn,
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
u32 avr_step;
|
u32 avr_step;
|
||||||
bool qsync_dirty, has_modeset;
|
bool qsync_dirty, has_modeset, ept;
|
||||||
struct drm_connector_state *conn_state = &sde_conn_state->base;
|
struct drm_connector_state *conn_state = &sde_conn_state->base;
|
||||||
u32 qsync_mode = sde_connector_get_property(&sde_conn_state->base,
|
u32 qsync_mode = sde_connector_get_property(&sde_conn_state->base,
|
||||||
CONNECTOR_PROP_QSYNC_MODE);
|
CONNECTOR_PROP_QSYNC_MODE);
|
||||||
@@ -1249,8 +1249,11 @@ static int _sde_encoder_atomic_check_qsync(struct sde_connector *sde_conn,
|
|||||||
has_modeset = sde_crtc_atomic_check_has_modeset(conn_state->state, conn_state->crtc);
|
has_modeset = sde_crtc_atomic_check_has_modeset(conn_state->state, conn_state->crtc);
|
||||||
qsync_dirty = msm_property_is_dirty(&sde_conn->property_info,
|
qsync_dirty = msm_property_is_dirty(&sde_conn->property_info,
|
||||||
&sde_conn_state->property_state, CONNECTOR_PROP_QSYNC_MODE);
|
&sde_conn_state->property_state, CONNECTOR_PROP_QSYNC_MODE);
|
||||||
|
ept = msm_property_is_dirty(&sde_conn->property_info,
|
||||||
|
&sde_conn_state->property_state, CONNECTOR_PROP_EPT);
|
||||||
|
|
||||||
if (has_modeset && qsync_dirty && (msm_is_mode_seamless_poms(&sde_conn_state->msm_mode) ||
|
if (has_modeset && (qsync_dirty || ept) &&
|
||||||
|
(msm_is_mode_seamless_poms(&sde_conn_state->msm_mode) ||
|
||||||
msm_is_mode_seamless_dyn_clk(&sde_conn_state->msm_mode))) {
|
msm_is_mode_seamless_dyn_clk(&sde_conn_state->msm_mode))) {
|
||||||
SDE_ERROR("invalid qsync update during modeset priv flag:%x\n",
|
SDE_ERROR("invalid qsync update during modeset priv flag:%x\n",
|
||||||
sde_conn_state->msm_mode.private_flags);
|
sde_conn_state->msm_mode.private_flags);
|
||||||
@@ -4642,6 +4645,56 @@ static int _sde_encoder_prepare_for_kickoff_processing(struct drm_encoder *drm_e
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _sde_encoder_delay_kickoff_processing(struct sde_encoder_virt *sde_enc)
|
||||||
|
{
|
||||||
|
ktime_t current_ts, ept_ts;
|
||||||
|
u32 avr_step_fps, min_fps = 0, qsync_mode;
|
||||||
|
u64 timeout_us = 0, ept;
|
||||||
|
struct drm_connector *drm_conn;
|
||||||
|
|
||||||
|
if (!sde_enc->cur_master || !sde_enc->cur_master->connector)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drm_conn = sde_enc->cur_master->connector;
|
||||||
|
ept = sde_connector_get_property(drm_conn->state, CONNECTOR_PROP_EPT);
|
||||||
|
if (!ept)
|
||||||
|
return;
|
||||||
|
|
||||||
|
avr_step_fps = sde_connector_get_avr_step(drm_conn);
|
||||||
|
qsync_mode = sde_connector_get_property(drm_conn->state, CONNECTOR_PROP_QSYNC_MODE);
|
||||||
|
if (qsync_mode)
|
||||||
|
_sde_encoder_get_qsync_fps_callback(&sde_enc->base, &min_fps, drm_conn->state);
|
||||||
|
/* use min qsync fps, if feature is enabled; otherwise min default fps */
|
||||||
|
min_fps = min_fps ? min_fps : DEFAULT_MIN_FPS;
|
||||||
|
|
||||||
|
current_ts = ktime_get_ns();
|
||||||
|
/* ept is in ns and avr_step is mulitple of refresh rate */
|
||||||
|
ept_ts = avr_step_fps ? ept - DIV_ROUND_UP(NSEC_PER_SEC, avr_step_fps) + NSEC_PER_MSEC
|
||||||
|
: ept - NSEC_PER_MSEC;
|
||||||
|
|
||||||
|
/* ept time already elapsed */
|
||||||
|
if (ept_ts <= current_ts) {
|
||||||
|
SDE_DEBUG("enc:%d, ept elapsed; ept:%llu, ept_ts:%llu, current_ts:%llu\n",
|
||||||
|
DRMID(&sde_enc->base), ept, ept_ts, current_ts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout_us = DIV_ROUND_UP((ept_ts - current_ts), 1000);
|
||||||
|
/* validate timeout is not beyond the min fps */
|
||||||
|
if (timeout_us > DIV_ROUND_UP(USEC_PER_SEC, min_fps)) {
|
||||||
|
SDE_ERROR("enc:%d, invalid timeout_us:%llu; ept:%llu, ept_ts:%llu, cur_ts:%llu\n",
|
||||||
|
DRMID(&sde_enc->base), timeout_us, ept, ept_ts, current_ts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDE_ATRACE_BEGIN("schedule_timeout");
|
||||||
|
usleep_range(timeout_us, timeout_us + 10);
|
||||||
|
SDE_ATRACE_END("schedule_timeout");
|
||||||
|
|
||||||
|
SDE_EVT32(DRMID(&sde_enc->base), qsync_mode, avr_step_fps, min_fps, ktime_to_us(current_ts),
|
||||||
|
ktime_to_us(ept_ts), timeout_us);
|
||||||
|
}
|
||||||
|
|
||||||
int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
|
int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
|
||||||
struct sde_encoder_kickoff_params *params)
|
struct sde_encoder_kickoff_params *params)
|
||||||
{
|
{
|
||||||
@@ -4715,6 +4768,8 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sde_encoder_delay_kickoff_processing(sde_enc);
|
||||||
|
|
||||||
ret = _sde_encoder_prepare_for_kickoff_processing(drm_enc, params, sde_enc, sde_kms,
|
ret = _sde_encoder_prepare_for_kickoff_processing(drm_enc, params, sde_enc, sde_kms,
|
||||||
needs_hw_reset, is_cmd_mode);
|
needs_hw_reset, is_cmd_mode);
|
||||||
|
|
||||||
|
@@ -59,6 +59,8 @@
|
|||||||
((!(phys_enc) || ((idx) < 0) || ((idx) >= INTR_IDX_MAX)) ? \
|
((!(phys_enc) || ((idx) < 0) || ((idx) >= INTR_IDX_MAX)) ? \
|
||||||
0 : ((phys_enc)->irq[(idx)].irq_idx >= 0))
|
0 : ((phys_enc)->irq[(idx)].irq_idx >= 0))
|
||||||
|
|
||||||
|
#define DEFAULT_MIN_FPS 10
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encoder functions and data types
|
* Encoder functions and data types
|
||||||
* @intfs: Interfaces this encoder is using, INTF_MODE_NONE if unused
|
* @intfs: Interfaces this encoder is using, INTF_MODE_NONE if unused
|
||||||
|
@@ -1339,7 +1339,12 @@ static void sde_encoder_phys_cmd_tearcheck_config(
|
|||||||
* disable sde hw generated TE signal, since hw TE will arrive first.
|
* disable sde hw generated TE signal, since hw TE will arrive first.
|
||||||
* Only caveat is if due to error, we hit wrap-around.
|
* Only caveat is if due to error, we hit wrap-around.
|
||||||
*/
|
*/
|
||||||
|
if (phys_enc->hw_intf->ops.is_te_32bit_supported
|
||||||
|
&& phys_enc->hw_intf->ops.is_te_32bit_supported(phys_enc->hw_intf))
|
||||||
|
tc_cfg.sync_cfg_height = 0xFFFFFFF0;
|
||||||
|
else
|
||||||
tc_cfg.sync_cfg_height = 0xFFF0;
|
tc_cfg.sync_cfg_height = 0xFFF0;
|
||||||
|
|
||||||
tc_cfg.vsync_init_val = mode->vdisplay;
|
tc_cfg.vsync_init_val = mode->vdisplay;
|
||||||
tc_cfg.sync_threshold_start = _get_tearcheck_threshold(phys_enc);
|
tc_cfg.sync_threshold_start = _get_tearcheck_threshold(phys_enc);
|
||||||
tc_cfg.sync_threshold_continue = DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE;
|
tc_cfg.sync_threshold_continue = DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE;
|
||||||
|
@@ -5395,6 +5395,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
|
|||||||
set_bit(SDE_FEATURE_SYS_CACHE_NSE, sde_cfg->features);
|
set_bit(SDE_FEATURE_SYS_CACHE_NSE, sde_cfg->features);
|
||||||
set_bit(SDE_FEATURE_SYS_CACHE_STALING, sde_cfg->features);
|
set_bit(SDE_FEATURE_SYS_CACHE_STALING, sde_cfg->features);
|
||||||
set_bit(SDE_FEATURE_WB_ROTATION, sde_cfg->features);
|
set_bit(SDE_FEATURE_WB_ROTATION, sde_cfg->features);
|
||||||
|
set_bit(SDE_FEATURE_EPT, sde_cfg->features);
|
||||||
sde_cfg->allowed_dsc_reservation_switch = SDE_DP_DSC_RESERVATION_SWITCH;
|
sde_cfg->allowed_dsc_reservation_switch = SDE_DP_DSC_RESERVATION_SWITCH;
|
||||||
sde_cfg->autorefresh_disable_seq = AUTOREFRESH_DISABLE_SEQ2;
|
sde_cfg->autorefresh_disable_seq = AUTOREFRESH_DISABLE_SEQ2;
|
||||||
sde_cfg->perf.min_prefill_lines = 40;
|
sde_cfg->perf.min_prefill_lines = 40;
|
||||||
|
@@ -767,6 +767,7 @@ enum {
|
|||||||
* @SDE_FEATURE_SUI_BLENDSTAGE SecureUI Blendstage supported
|
* @SDE_FEATURE_SUI_BLENDSTAGE SecureUI Blendstage supported
|
||||||
* @SDE_FEATURE_SUI_NS_ALLOWED SecureUI allowed to access non-secure context banks
|
* @SDE_FEATURE_SUI_NS_ALLOWED SecureUI allowed to access non-secure context banks
|
||||||
* @SDE_FEATURE_TRUSTED_VM Trusted VM supported
|
* @SDE_FEATURE_TRUSTED_VM Trusted VM supported
|
||||||
|
* @SDE_FEATURE_EPT Expected present time supported
|
||||||
* @SDE_FEATURE_UBWC_STATS UBWC statistics supported
|
* @SDE_FEATURE_UBWC_STATS UBWC statistics supported
|
||||||
* @SDE_FEATURE_VBIF_CLK_SPLIT VBIF clock split supported
|
* @SDE_FEATURE_VBIF_CLK_SPLIT VBIF clock split supported
|
||||||
* @SDE_FEATURE_CTL_DONE Support for CTL DONE irq
|
* @SDE_FEATURE_CTL_DONE Support for CTL DONE irq
|
||||||
@@ -813,6 +814,7 @@ enum sde_mdss_features {
|
|||||||
SDE_FEATURE_SUI_BLENDSTAGE,
|
SDE_FEATURE_SUI_BLENDSTAGE,
|
||||||
SDE_FEATURE_SUI_NS_ALLOWED,
|
SDE_FEATURE_SUI_NS_ALLOWED,
|
||||||
SDE_FEATURE_TRUSTED_VM,
|
SDE_FEATURE_TRUSTED_VM,
|
||||||
|
SDE_FEATURE_EPT,
|
||||||
SDE_FEATURE_UBWC_STATS,
|
SDE_FEATURE_UBWC_STATS,
|
||||||
SDE_FEATURE_VBIF_CLK_SPLIT,
|
SDE_FEATURE_VBIF_CLK_SPLIT,
|
||||||
SDE_FEATURE_CTL_DONE,
|
SDE_FEATURE_CTL_DONE,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -1022,6 +1022,11 @@ static void sde_hw_intf_enable_wide_bus(struct sde_hw_intf *intf,
|
|||||||
SDE_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
|
SDE_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sde_hw_intf_is_te_32bit_supported(struct sde_hw_intf *intf)
|
||||||
|
{
|
||||||
|
return (intf->cap->features & BIT(SDE_INTF_TE_32BIT));
|
||||||
|
}
|
||||||
|
|
||||||
static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
|
static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
|
||||||
unsigned long cap)
|
unsigned long cap)
|
||||||
{
|
{
|
||||||
@@ -1038,6 +1043,7 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
|
|||||||
ops->avr_ctrl = sde_hw_intf_avr_ctrl;
|
ops->avr_ctrl = sde_hw_intf_avr_ctrl;
|
||||||
ops->enable_compressed_input = sde_hw_intf_enable_compressed_input;
|
ops->enable_compressed_input = sde_hw_intf_enable_compressed_input;
|
||||||
ops->enable_wide_bus = sde_hw_intf_enable_wide_bus;
|
ops->enable_wide_bus = sde_hw_intf_enable_wide_bus;
|
||||||
|
ops->is_te_32bit_supported = sde_hw_intf_is_te_32bit_supported;
|
||||||
|
|
||||||
if (cap & BIT(SDE_INTF_STATUS))
|
if (cap & BIT(SDE_INTF_STATUS))
|
||||||
ops->get_status = sde_hw_intf_v1_get_status;
|
ops->get_status = sde_hw_intf_v1_get_status;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -267,6 +267,11 @@ struct sde_hw_intf_ops {
|
|||||||
*/
|
*/
|
||||||
void (*override_tear_rd_ptr_val)(struct sde_hw_intf *intf,
|
void (*override_tear_rd_ptr_val)(struct sde_hw_intf *intf,
|
||||||
u32 adjusted_linecnt);
|
u32 adjusted_linecnt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if intf supports 32-bit registers for TE
|
||||||
|
*/
|
||||||
|
bool (*is_te_32bit_supported)(struct sde_hw_intf *intf);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sde_hw_intf {
|
struct sde_hw_intf {
|
||||||
|
Reference in New Issue
Block a user