disp: msm: add support for INTF WD jitter
Change adds support for the INTF watchdog timer jitter feature for MDSS 9.x. Change-Id: I2cf821b5b5724f9adee95c282e0ec09719489a85 Signed-off-by: Satya Rama Aditya Pinapala <quic_spinapal@quicinc.com> Signed-off-by: Narendra Muppalla <quic_nmuppall@quicinc.com>
This commit is contained in:

committed by
Narendra Muppalla

parent
7d0468f562
commit
718cd25496
@@ -1,5 +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) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -620,6 +621,7 @@ struct dsi_host_config {
|
|||||||
* @topology: Topology selected for the panel
|
* @topology: Topology selected for the panel
|
||||||
* @dsc: DSC compression info
|
* @dsc: DSC compression info
|
||||||
* @vdc: VDC compression info
|
* @vdc: VDC compression info
|
||||||
|
* @wd_jitter: WD Jitter config.
|
||||||
* @dsc_enabled: DSC compression enabled
|
* @dsc_enabled: DSC compression enabled
|
||||||
* @vdc_enabled: VDC compression enabled
|
* @vdc_enabled: VDC compression enabled
|
||||||
* @pclk_scale: pclk scale factor, target bpp to source bpp
|
* @pclk_scale: pclk scale factor, target bpp to source bpp
|
||||||
@@ -647,6 +649,7 @@ struct dsi_display_mode_priv_info {
|
|||||||
struct msm_display_topology topology;
|
struct msm_display_topology topology;
|
||||||
struct msm_display_dsc_info dsc;
|
struct msm_display_dsc_info dsc;
|
||||||
struct msm_display_vdc_info vdc;
|
struct msm_display_vdc_info vdc;
|
||||||
|
struct msm_display_wd_jitter_config wd_jitter;
|
||||||
bool dsc_enabled;
|
bool dsc_enabled;
|
||||||
bool vdc_enabled;
|
bool vdc_enabled;
|
||||||
struct msm_ratio pclk_scale;
|
struct msm_ratio pclk_scale;
|
||||||
|
@@ -638,6 +638,7 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
|
|||||||
dsi_mode->priv_info->mdp_transfer_time_us;
|
dsi_mode->priv_info->mdp_transfer_time_us;
|
||||||
mode_info->disable_rsc_solver = dsi_mode->priv_info->disable_rsc_solver;
|
mode_info->disable_rsc_solver = dsi_mode->priv_info->disable_rsc_solver;
|
||||||
mode_info->qsync_min_fps = dsi_mode->timing.qsync_min_fps;
|
mode_info->qsync_min_fps = dsi_mode->timing.qsync_min_fps;
|
||||||
|
mode_info->wd_jitter = dsi_mode->priv_info->wd_jitter;
|
||||||
|
|
||||||
memcpy(&mode_info->topology, &dsi_mode->priv_info->topology,
|
memcpy(&mode_info->topology, &dsi_mode->priv_info->topology,
|
||||||
sizeof(struct msm_display_topology));
|
sizeof(struct msm_display_topology));
|
||||||
|
@@ -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-2022 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -2203,16 +2203,71 @@ static int dsi_panel_parse_misc_features(struct dsi_panel *panel)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dsi_panel_parse_wd_jitter_config(struct dsi_display_mode_priv_info *priv_info,
|
||||||
|
struct dsi_parser_utils *utils, u32 *jitter)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct msm_display_wd_jitter_config *wd_jitter = &priv_info->wd_jitter;
|
||||||
|
u32 ltj[DEFAULT_PANEL_JITTER_ARRAY_SIZE] = {0, 1};
|
||||||
|
u32 ltj_time = 0;
|
||||||
|
const u32 min_ltj = 10;
|
||||||
|
|
||||||
|
if (!(utils->read_bool(utils->data, "qcom,dsi-wd-jitter-enable"))) {
|
||||||
|
priv_info->panel_jitter_numer = DEFAULT_PANEL_JITTER_NUMERATOR;
|
||||||
|
priv_info->panel_jitter_denom = DEFAULT_PANEL_JITTER_DENOMINATOR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = utils->read_u32_array(utils->data, "qcom,dsi-wd-ltj-max-jitter", ltj,
|
||||||
|
DEFAULT_PANEL_JITTER_ARRAY_SIZE);
|
||||||
|
rc |= utils->read_u32(utils->data, "qcom,dsi-wd-ltj-time-sec", <j_time);
|
||||||
|
if (rc || !ltj[1] || !ltj_time || (ltj[0] / ltj[1] < min_ltj)) {
|
||||||
|
DSI_DEBUG("No valid long term jitter defined\n");
|
||||||
|
priv_info->panel_jitter_numer = DEFAULT_PANEL_JITTER_NUMERATOR;
|
||||||
|
priv_info->panel_jitter_denom = DEFAULT_PANEL_JITTER_DENOMINATOR;
|
||||||
|
rc = -EINVAL;
|
||||||
|
} else {
|
||||||
|
wd_jitter->ltj_max_numer = ltj[0];
|
||||||
|
wd_jitter->ltj_max_denom = ltj[1];
|
||||||
|
wd_jitter->ltj_time_sec = ltj_time;
|
||||||
|
wd_jitter->jitter_type = MSM_DISPLAY_WD_LTJ_JITTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jitter[0] && jitter[1]) {
|
||||||
|
if (jitter[0] / jitter[1] > MAX_PANEL_JITTER) {
|
||||||
|
wd_jitter->inst_jitter_numer = DEFAULT_PANEL_JITTER_NUMERATOR;
|
||||||
|
wd_jitter->inst_jitter_denom = DEFAULT_PANEL_JITTER_DENOMINATOR;
|
||||||
|
} else {
|
||||||
|
wd_jitter->inst_jitter_numer = jitter[0];
|
||||||
|
wd_jitter->inst_jitter_denom = jitter[1];
|
||||||
|
}
|
||||||
|
wd_jitter->jitter_type |= MSM_DISPLAY_WD_INSTANTANEOUS_JITTER;
|
||||||
|
} else if (rc) {
|
||||||
|
wd_jitter->inst_jitter_numer = DEFAULT_PANEL_JITTER_NUMERATOR;
|
||||||
|
wd_jitter->inst_jitter_denom = DEFAULT_PANEL_JITTER_DENOMINATOR;
|
||||||
|
wd_jitter->jitter_type |= MSM_DISPLAY_WD_INSTANTANEOUS_JITTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv_info->panel_jitter_numer = rc ?
|
||||||
|
wd_jitter->inst_jitter_numer : wd_jitter->ltj_max_numer;
|
||||||
|
priv_info->panel_jitter_denom = rc ?
|
||||||
|
wd_jitter->inst_jitter_denom : wd_jitter->ltj_max_denom;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int dsi_panel_parse_jitter_config(
|
static int dsi_panel_parse_jitter_config(
|
||||||
struct dsi_display_mode *mode,
|
struct dsi_display_mode *mode,
|
||||||
struct dsi_parser_utils *utils)
|
struct dsi_parser_utils *utils)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct dsi_display_mode_priv_info *priv_info;
|
struct dsi_display_mode_priv_info *priv_info;
|
||||||
|
struct dsi_panel *panel;
|
||||||
u32 jitter[DEFAULT_PANEL_JITTER_ARRAY_SIZE] = {0, 0};
|
u32 jitter[DEFAULT_PANEL_JITTER_ARRAY_SIZE] = {0, 0};
|
||||||
u64 jitter_val = 0;
|
u64 jitter_val = 0;
|
||||||
|
|
||||||
priv_info = mode->priv_info;
|
priv_info = mode->priv_info;
|
||||||
|
panel = container_of(utils, struct dsi_panel, utils);
|
||||||
|
|
||||||
rc = utils->read_u32_array(utils->data, "qcom,mdss-dsi-panel-jitter",
|
rc = utils->read_u32_array(utils->data, "qcom,mdss-dsi-panel-jitter",
|
||||||
jitter, DEFAULT_PANEL_JITTER_ARRAY_SIZE);
|
jitter, DEFAULT_PANEL_JITTER_ARRAY_SIZE);
|
||||||
@@ -2223,10 +2278,11 @@ static int dsi_panel_parse_jitter_config(
|
|||||||
jitter_val = div_u64(jitter_val, jitter[1]);
|
jitter_val = div_u64(jitter_val, jitter[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc || !jitter_val || (jitter_val > MAX_PANEL_JITTER)) {
|
if (panel->te_using_watchdog_timer) {
|
||||||
|
dsi_panel_parse_wd_jitter_config(priv_info, utils, jitter);
|
||||||
|
} else if (rc || !jitter_val || (jitter_val > MAX_PANEL_JITTER)) {
|
||||||
priv_info->panel_jitter_numer = DEFAULT_PANEL_JITTER_NUMERATOR;
|
priv_info->panel_jitter_numer = DEFAULT_PANEL_JITTER_NUMERATOR;
|
||||||
priv_info->panel_jitter_denom =
|
priv_info->panel_jitter_denom = DEFAULT_PANEL_JITTER_DENOMINATOR;
|
||||||
DEFAULT_PANEL_JITTER_DENOMINATOR;
|
|
||||||
} else {
|
} else {
|
||||||
priv_info->panel_jitter_numer = jitter[0];
|
priv_info->panel_jitter_numer = jitter[0];
|
||||||
priv_info->panel_jitter_denom = jitter[1];
|
priv_info->panel_jitter_denom = jitter[1];
|
||||||
|
@@ -257,6 +257,18 @@ enum msm_display_compression_type {
|
|||||||
MSM_DISPLAY_COMPRESSION_VDC
|
MSM_DISPLAY_COMPRESSION_VDC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum msm_display_wd_jitter_type - Type of WD jitter used
|
||||||
|
* @MSM_DISPLAY_WD_JITTER_NONE: No WD timer jitter enabled
|
||||||
|
* @MSM_DISPLAY_WD_INSTANTANEOUS_JITTER: Instantaneous WD jitter enabled
|
||||||
|
* @MSM_DISPLAY_WD_LTJ_JITTER: LTJ WD jitter enabled
|
||||||
|
*/
|
||||||
|
enum msm_display_wd_jitter_type {
|
||||||
|
MSM_DISPLAY_WD_JITTER_NONE = BIT(0),
|
||||||
|
MSM_DISPLAY_WD_INSTANTANEOUS_JITTER = BIT(1),
|
||||||
|
MSM_DISPLAY_WD_LTJ_JITTER = BIT(2),
|
||||||
|
};
|
||||||
|
|
||||||
#define MSM_DISPLAY_COMPRESSION_RATIO_NONE 1
|
#define MSM_DISPLAY_COMPRESSION_RATIO_NONE 1
|
||||||
#define MSM_DISPLAY_COMPRESSION_RATIO_MAX 5
|
#define MSM_DISPLAY_COMPRESSION_RATIO_MAX 5
|
||||||
|
|
||||||
@@ -744,6 +756,24 @@ struct msm_dyn_clk_list {
|
|||||||
u32 *pixel_clks_khz;
|
u32 *pixel_clks_khz;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct msm_display_wd_jitter_config - defines jitter properties for WD timer
|
||||||
|
* @jitter_type: Type of WD jitter enabled.
|
||||||
|
* @inst_jitter_numer: Instantaneous jitter numerator.
|
||||||
|
* @inst_jitter_denom: Instantaneous jitter denominator.
|
||||||
|
* @ltj_max_numer: LTJ max numerator.
|
||||||
|
* @ltj_max_denom: LTJ max denominator.
|
||||||
|
* @ltj_time_sec: LTJ time in seconds.
|
||||||
|
*/
|
||||||
|
struct msm_display_wd_jitter_config {
|
||||||
|
enum msm_display_wd_jitter_type jitter_type;
|
||||||
|
u32 inst_jitter_numer;
|
||||||
|
u32 inst_jitter_denom;
|
||||||
|
u32 ltj_max_numer;
|
||||||
|
u32 ltj_max_denom;
|
||||||
|
u32 ltj_time_sec;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct msm_mode_info - defines all msm custom mode info
|
* struct msm_mode_info - defines all msm custom mode info
|
||||||
* @frame_rate: frame_rate of the mode
|
* @frame_rate: frame_rate of the mode
|
||||||
@@ -764,6 +794,7 @@ struct msm_dyn_clk_list {
|
|||||||
* @disable_rsc_solver: Dynamically disable RSC solver for the timing mode due to lower bitclk rate.
|
* @disable_rsc_solver: Dynamically disable RSC solver for the timing mode due to lower bitclk rate.
|
||||||
* @dyn_clk_list: List of dynamic clock rates for RFI.
|
* @dyn_clk_list: List of dynamic clock rates for RFI.
|
||||||
* @qsync_min_fps: qsync min fps rate
|
* @qsync_min_fps: qsync min fps rate
|
||||||
|
* @wd_jitter: Info for WD jitter.
|
||||||
*/
|
*/
|
||||||
struct msm_mode_info {
|
struct msm_mode_info {
|
||||||
uint32_t frame_rate;
|
uint32_t frame_rate;
|
||||||
@@ -783,6 +814,7 @@ struct msm_mode_info {
|
|||||||
bool disable_rsc_solver;
|
bool disable_rsc_solver;
|
||||||
struct msm_dyn_clk_list dyn_clk_list;
|
struct msm_dyn_clk_list dyn_clk_list;
|
||||||
u32 qsync_min_fps;
|
u32 qsync_min_fps;
|
||||||
|
struct msm_display_wd_jitter_config wd_jitter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1894,11 +1894,38 @@ static void sde_encoder_phys_cmd_trigger_start(
|
|||||||
cmd_enc->wr_ptr_wait_success = false;
|
cmd_enc->wr_ptr_wait_success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _sde_encoder_phys_cmd_calculate_wd_params(struct sde_encoder_phys *phys_enc,
|
||||||
|
struct intf_wd_jitter_params *wd_jitter)
|
||||||
|
{
|
||||||
|
u32 nominal_te_value;
|
||||||
|
struct sde_encoder_virt *sde_enc;
|
||||||
|
struct msm_mode_info *mode_info;
|
||||||
|
const u32 multiplier = 1 << 10;
|
||||||
|
|
||||||
|
sde_enc = to_sde_encoder_virt(phys_enc->parent);
|
||||||
|
mode_info = &sde_enc->mode_info;
|
||||||
|
|
||||||
|
if (mode_info->wd_jitter.jitter_type & MSM_DISPLAY_WD_INSTANTANEOUS_JITTER)
|
||||||
|
wd_jitter->jitter = mult_frac(multiplier, mode_info->wd_jitter.inst_jitter_numer,
|
||||||
|
(mode_info->wd_jitter.inst_jitter_denom * 100));
|
||||||
|
|
||||||
|
if (mode_info->wd_jitter.jitter_type & MSM_DISPLAY_WD_LTJ_JITTER) {
|
||||||
|
nominal_te_value = CALCULATE_WD_LOAD_VALUE(mode_info->frame_rate) * MDP_TICK_COUNT;
|
||||||
|
wd_jitter->ltj_max = mult_frac(nominal_te_value, mode_info->wd_jitter.ltj_max_numer,
|
||||||
|
(mode_info->wd_jitter.ltj_max_denom) * 100);
|
||||||
|
wd_jitter->ltj_slope = mult_frac((1 << 16), wd_jitter->ltj_max,
|
||||||
|
(mode_info->wd_jitter.ltj_time_sec * mode_info->frame_rate));
|
||||||
|
}
|
||||||
|
|
||||||
|
phys_enc->hw_intf->ops.configure_wd_jitter(phys_enc->hw_intf, wd_jitter);
|
||||||
|
}
|
||||||
|
|
||||||
static void sde_encoder_phys_cmd_setup_vsync_source(struct sde_encoder_phys *phys_enc,
|
static void sde_encoder_phys_cmd_setup_vsync_source(struct sde_encoder_phys *phys_enc,
|
||||||
u32 vsync_source, struct msm_display_info *disp_info)
|
u32 vsync_source, struct msm_display_info *disp_info)
|
||||||
{
|
{
|
||||||
struct sde_encoder_virt *sde_enc;
|
struct sde_encoder_virt *sde_enc;
|
||||||
struct sde_connector *sde_conn;
|
struct sde_connector *sde_conn;
|
||||||
|
struct intf_wd_jitter_params wd_jitter = {0, 0};
|
||||||
|
|
||||||
if (!phys_enc || !phys_enc->hw_intf)
|
if (!phys_enc || !phys_enc->hw_intf)
|
||||||
return;
|
return;
|
||||||
@@ -1912,6 +1939,8 @@ static void sde_encoder_phys_cmd_setup_vsync_source(struct sde_encoder_phys *phy
|
|||||||
if ((disp_info->is_te_using_watchdog_timer || sde_conn->panel_dead) &&
|
if ((disp_info->is_te_using_watchdog_timer || sde_conn->panel_dead) &&
|
||||||
phys_enc->hw_intf->ops.setup_vsync_source) {
|
phys_enc->hw_intf->ops.setup_vsync_source) {
|
||||||
vsync_source = SDE_VSYNC_SOURCE_WD_TIMER_0;
|
vsync_source = SDE_VSYNC_SOURCE_WD_TIMER_0;
|
||||||
|
if (phys_enc->hw_intf->ops.configure_wd_jitter)
|
||||||
|
_sde_encoder_phys_cmd_calculate_wd_params(phys_enc, &wd_jitter);
|
||||||
phys_enc->hw_intf->ops.setup_vsync_source(phys_enc->hw_intf,
|
phys_enc->hw_intf->ops.setup_vsync_source(phys_enc->hw_intf,
|
||||||
sde_enc->mode_info.frame_rate);
|
sde_enc->mode_info.frame_rate);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -2366,6 +2366,7 @@ static int sde_intf_parse_dt(struct device_node *np,
|
|||||||
|
|
||||||
if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_900)) {
|
if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_900)) {
|
||||||
set_bit(SDE_INTF_MDP_VSYNC_TS, &intf->features);
|
set_bit(SDE_INTF_MDP_VSYNC_TS, &intf->features);
|
||||||
|
set_bit(SDE_INTF_WD_JITTER, &intf->features);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -567,6 +567,7 @@ enum {
|
|||||||
* @SDE_INTF_PANEL_VSYNC_TS INTF block has panel vsync timestamp logged
|
* @SDE_INTF_PANEL_VSYNC_TS INTF block has panel vsync timestamp logged
|
||||||
* @SDE_INTF_MDP_VSYNC_TS INTF block has mdp vsync timestamp logged
|
* @SDE_INTF_MDP_VSYNC_TS INTF block has mdp vsync timestamp logged
|
||||||
* @SDE_INTF_AVR_STATUS INTF block has AVR_STATUS field in AVR_CONTROL register
|
* @SDE_INTF_AVR_STATUS INTF block has AVR_STATUS field in AVR_CONTROL register
|
||||||
|
* @SDE_INTF_WD_JITTER INTF block has WD timer jitter support
|
||||||
* @SDE_INTF_MAX
|
* @SDE_INTF_MAX
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
@@ -579,6 +580,7 @@ enum {
|
|||||||
SDE_INTF_PANEL_VSYNC_TS,
|
SDE_INTF_PANEL_VSYNC_TS,
|
||||||
SDE_INTF_MDP_VSYNC_TS,
|
SDE_INTF_MDP_VSYNC_TS,
|
||||||
SDE_INTF_AVR_STATUS,
|
SDE_INTF_AVR_STATUS,
|
||||||
|
SDE_INTF_WD_JITTER,
|
||||||
SDE_INTF_MAX
|
SDE_INTF_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2022 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -69,6 +69,9 @@
|
|||||||
#define INTF_VSYNC_TIMESTAMP1 0x218
|
#define INTF_VSYNC_TIMESTAMP1 0x218
|
||||||
#define INTF_MDP_VSYNC_TIMESTAMP0 0x21C
|
#define INTF_MDP_VSYNC_TIMESTAMP0 0x21C
|
||||||
#define INTF_MDP_VSYNC_TIMESTAMP1 0x220
|
#define INTF_MDP_VSYNC_TIMESTAMP1 0x220
|
||||||
|
#define INTF_WD_TIMER_0_JITTER_CTL 0x224
|
||||||
|
#define INTF_WD_TIMER_0_LTJ_SLOPE 0x228
|
||||||
|
#define INTF_WD_TIMER_0_LTJ_MAX 0x22C
|
||||||
#define INTF_WD_TIMER_0_CTL 0x230
|
#define INTF_WD_TIMER_0_CTL 0x230
|
||||||
#define INTF_WD_TIMER_0_CTL2 0x234
|
#define INTF_WD_TIMER_0_CTL2 0x234
|
||||||
#define INTF_WD_TIMER_0_LOAD_VALUE 0x238
|
#define INTF_WD_TIMER_0_LOAD_VALUE 0x238
|
||||||
@@ -455,8 +458,39 @@ static void sde_hw_intf_setup_prg_fetch(
|
|||||||
SDE_REG_WRITE(c, INTF_CONFIG, fetch_enable);
|
SDE_REG_WRITE(c, INTF_CONFIG, fetch_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sde_hw_intf_setup_vsync_source(struct sde_hw_intf *intf,
|
static void sde_hw_intf_configure_wd_timer_jitter(struct sde_hw_intf *intf,
|
||||||
u32 frame_rate)
|
struct intf_wd_jitter_params *wd_jitter)
|
||||||
|
{
|
||||||
|
struct sde_hw_blk_reg_map *c;
|
||||||
|
u32 reg, jitter_ctl = 0;
|
||||||
|
|
||||||
|
c = &intf->hw;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load Jitter values with jitter feature disabled.
|
||||||
|
*/
|
||||||
|
SDE_REG_WRITE(c, INTF_WD_TIMER_0_JITTER_CTL, 0x1);
|
||||||
|
|
||||||
|
if (wd_jitter->jitter)
|
||||||
|
jitter_ctl |= ((wd_jitter->jitter & 0x3FF) << 16);
|
||||||
|
|
||||||
|
if (wd_jitter->ltj_max) {
|
||||||
|
SDE_REG_WRITE(c, INTF_WD_TIMER_0_LTJ_MAX, wd_jitter->ltj_max);
|
||||||
|
SDE_REG_WRITE(c, INTF_WD_TIMER_0_LTJ_SLOPE, wd_jitter->ltj_slope);
|
||||||
|
}
|
||||||
|
|
||||||
|
reg = SDE_REG_READ(c, INTF_WD_TIMER_0_JITTER_CTL);
|
||||||
|
reg |= jitter_ctl;
|
||||||
|
SDE_REG_WRITE(c, INTF_WD_TIMER_0_JITTER_CTL, reg);
|
||||||
|
|
||||||
|
if (wd_jitter->jitter)
|
||||||
|
reg |= BIT(31);
|
||||||
|
if (wd_jitter->ltj_max)
|
||||||
|
reg |= BIT(30);
|
||||||
|
SDE_REG_WRITE(c, INTF_WD_TIMER_0_JITTER_CTL, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sde_hw_intf_setup_vsync_source(struct sde_hw_intf *intf, u32 frame_rate)
|
||||||
{
|
{
|
||||||
struct sde_hw_blk_reg_map *c;
|
struct sde_hw_blk_reg_map *c;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
@@ -466,7 +500,11 @@ static void sde_hw_intf_setup_vsync_source(struct sde_hw_intf *intf,
|
|||||||
|
|
||||||
c = &intf->hw;
|
c = &intf->hw;
|
||||||
|
|
||||||
SDE_REG_WRITE(c, INTF_WD_TIMER_0_LOAD_VALUE, CALCULATE_WD_LOAD_VALUE(frame_rate));
|
reg = CALCULATE_WD_LOAD_VALUE(frame_rate);
|
||||||
|
if (intf->cap->features & BIT(SDE_INTF_WD_JITTER))
|
||||||
|
reg *= MDP_TICK_COUNT;
|
||||||
|
|
||||||
|
SDE_REG_WRITE(c, INTF_WD_TIMER_0_LOAD_VALUE, reg);
|
||||||
|
|
||||||
SDE_REG_WRITE(c, INTF_WD_TIMER_0_CTL, BIT(0)); /* clear timer */
|
SDE_REG_WRITE(c, INTF_WD_TIMER_0_CTL, BIT(0)); /* clear timer */
|
||||||
reg = SDE_REG_READ(c, INTF_WD_TIMER_0_CTL2);
|
reg = SDE_REG_READ(c, INTF_WD_TIMER_0_CTL2);
|
||||||
@@ -928,6 +966,9 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
|
|||||||
|
|
||||||
if (cap & (BIT(SDE_INTF_PANEL_VSYNC_TS) | BIT(SDE_INTF_MDP_VSYNC_TS)))
|
if (cap & (BIT(SDE_INTF_PANEL_VSYNC_TS) | BIT(SDE_INTF_MDP_VSYNC_TS)))
|
||||||
ops->get_vsync_timestamp = sde_hw_intf_get_vsync_timestamp;
|
ops->get_vsync_timestamp = sde_hw_intf_get_vsync_timestamp;
|
||||||
|
|
||||||
|
if (cap & BIT(SDE_INTF_WD_JITTER))
|
||||||
|
ops->configure_wd_jitter = sde_hw_intf_configure_wd_timer_jitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sde_hw_blk_reg_map *sde_hw_intf_init(enum sde_intf idx,
|
struct sde_hw_blk_reg_map *sde_hw_intf_init(enum sde_intf idx,
|
||||||
|
@@ -1,5 +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) 2015-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -65,6 +66,17 @@ struct intf_avr_params {
|
|||||||
u32 avr_mode; /* one of enum @sde_rm_qsync_modes */
|
u32 avr_mode; /* one of enum @sde_rm_qsync_modes */
|
||||||
u32 avr_step_lines; /* 0 or 1 means disabled */
|
u32 avr_step_lines; /* 0 or 1 means disabled */
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* struct intf_wd_jitter_params : Interface to the INTF WD Jitter params.
|
||||||
|
* jitter : max instantaneous jitter.
|
||||||
|
* ltj_max : max long term jitter value.
|
||||||
|
* ltj_slope : slope of long term jitter.
|
||||||
|
*/
|
||||||
|
struct intf_wd_jitter_params {
|
||||||
|
u32 jitter;
|
||||||
|
u32 ltj_max;
|
||||||
|
u32 ltj_slope;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct sde_hw_intf_ops : Interface to the interface Hw driver functions
|
* struct sde_hw_intf_ops : Interface to the interface Hw driver functions
|
||||||
@@ -80,6 +92,7 @@ struct intf_avr_params {
|
|||||||
* @ get_underrun_line_count: reads current underrun pixel clock count and
|
* @ get_underrun_line_count: reads current underrun pixel clock count and
|
||||||
* converts it into line count
|
* converts it into line count
|
||||||
* @setup_vsync_source: Configure vsync source selection for intf
|
* @setup_vsync_source: Configure vsync source selection for intf
|
||||||
|
* @configure_wd_jitter: Configure WD jitter.
|
||||||
* @bind_pingpong_blk: enable/disable the connection with pingpong which will
|
* @bind_pingpong_blk: enable/disable the connection with pingpong which will
|
||||||
* feed pixels to this interface
|
* feed pixels to this interface
|
||||||
*/
|
*/
|
||||||
@@ -115,6 +128,8 @@ struct sde_hw_intf_ops {
|
|||||||
u32 (*get_underrun_line_count)(struct sde_hw_intf *intf);
|
u32 (*get_underrun_line_count)(struct sde_hw_intf *intf);
|
||||||
|
|
||||||
void (*setup_vsync_source)(struct sde_hw_intf *intf, u32 frame_rate);
|
void (*setup_vsync_source)(struct sde_hw_intf *intf, u32 frame_rate);
|
||||||
|
void (*configure_wd_jitter)(struct sde_hw_intf *intf,
|
||||||
|
struct intf_wd_jitter_params *wd_jitter);
|
||||||
|
|
||||||
void (*bind_pingpong_blk)(struct sde_hw_intf *intf,
|
void (*bind_pingpong_blk)(struct sde_hw_intf *intf,
|
||||||
bool enable,
|
bool enable,
|
||||||
|
Reference in New Issue
Block a user