Merge "disp: msm: sde: pass sde_enc to sde_encoder_control_te"

This commit is contained in:
qctecmdr
2022-10-28 18:12:45 -07:00
committed by Gerrit - the friendly Code Review server
9 changed files with 123 additions and 47 deletions

View File

@@ -5040,18 +5040,8 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg)
break; break;
case SDE_POWER_EVENT_PRE_DISABLE: case SDE_POWER_EVENT_PRE_DISABLE:
drm_for_each_encoder_mask(encoder, crtc->dev, drm_for_each_encoder_mask(encoder, crtc->dev,
crtc->state->encoder_mask) { crtc->state->encoder_mask)
/* sde_encoder_idle_pc_enter(encoder);
* disable the vsync source after updating the
* rsc state. rsc state update might have vsync wait
* and vsync source must be disabled after it.
* It will avoid generating any vsync from this point
* till mode-2 entry. It is SW workaround for HW
* limitation and should not be removed without
* checking the updated design.
*/
sde_encoder_control_te(encoder, false);
}
spin_lock_irqsave(&sde_crtc->spin_lock, flags); spin_lock_irqsave(&sde_crtc->spin_lock, flags);
node = NULL; node = NULL;

View File

@@ -1453,6 +1453,22 @@ static void _sde_encoder_update_vsync_source(struct sde_encoder_virt *sde_enc,
} }
} }
static void sde_encoder_control_te(struct sde_encoder_virt *sde_enc, bool enable)
{
struct sde_encoder_phys *phys;
int i;
if (!sde_enc) {
SDE_ERROR("invalid sde encoder\n");
return;
}
for (i = 0; i < sde_enc->num_phys_encs; i++) {
phys = sde_enc->phys_encs[i];
if (phys && phys->ops.control_te)
phys->ops.control_te(phys, enable);
}
}
int sde_encoder_helper_switch_vsync(struct drm_encoder *drm_enc, int sde_encoder_helper_switch_vsync(struct drm_encoder *drm_enc,
@@ -1468,13 +1484,13 @@ int sde_encoder_helper_switch_vsync(struct drm_encoder *drm_enc,
sde_enc = to_sde_encoder_virt(drm_enc); sde_enc = to_sde_encoder_virt(drm_enc);
sde_encoder_control_te(drm_enc, false); sde_encoder_control_te(sde_enc, false);
memcpy(&disp_info, &sde_enc->disp_info, sizeof(disp_info)); memcpy(&disp_info, &sde_enc->disp_info, sizeof(disp_info));
disp_info.is_te_using_watchdog_timer = watchdog_te; disp_info.is_te_using_watchdog_timer = watchdog_te;
_sde_encoder_update_vsync_source(sde_enc, &disp_info); _sde_encoder_update_vsync_source(sde_enc, &disp_info);
sde_encoder_control_te(drm_enc, true); sde_encoder_control_te(sde_enc, true);
return 0; return 0;
} }
@@ -2183,9 +2199,9 @@ static int _sde_encoder_rc_post_modeset(struct drm_encoder *drm_enc,
/* toggle te bit to update vsync source for sim cmd mode panels */ /* toggle te bit to update vsync source for sim cmd mode panels */
if (sde_encoder_check_curr_mode(&sde_enc->base, MSM_DISPLAY_CMD_MODE) if (sde_encoder_check_curr_mode(&sde_enc->base, MSM_DISPLAY_CMD_MODE)
&& sde_enc->disp_info.is_te_using_watchdog_timer) { && sde_enc->disp_info.is_te_using_watchdog_timer) {
sde_encoder_control_te(drm_enc, false); sde_encoder_control_te(sde_enc, false);
_sde_encoder_update_vsync_source(sde_enc, &sde_enc->disp_info); _sde_encoder_update_vsync_source(sde_enc, &sde_enc->disp_info);
sde_encoder_control_te(drm_enc, true); sde_encoder_control_te(sde_enc, true);
} }
_sde_encoder_update_rsc_client(drm_enc, true); _sde_encoder_update_rsc_client(drm_enc, true);
@@ -2728,28 +2744,28 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
sde_encoder_virt_modeset_rc(drm_enc, adj_mode, msm_mode, false); sde_encoder_virt_modeset_rc(drm_enc, adj_mode, msm_mode, false);
} }
void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable) void sde_encoder_idle_pc_enter(struct drm_encoder *drm_enc)
{ {
struct sde_encoder_virt *sde_enc; struct sde_encoder_virt *sde_enc = NULL;
struct sde_encoder_phys *phys;
int i;
if (!drm_enc) { if (!drm_enc) {
SDE_ERROR("invalid parameters\n"); SDE_ERROR("invalid encoder\n");
return; return;
} }
sde_enc = to_sde_encoder_virt(drm_enc); sde_enc = to_sde_encoder_virt(drm_enc);
if (!sde_enc) { /*
SDE_ERROR("invalid sde encoder\n"); * disable the vsync source after updating the
return; * rsc state. rsc state update might have vsync wait
} * and vsync source must be disabled after it.
* It will avoid generating any vsync from this point
* till mode-2 entry. It is SW workaround for HW
* limitation and should not be removed without
* checking the updated design.
*/
sde_encoder_control_te(sde_enc, false);
for (i = 0; i < sde_enc->num_phys_encs; i++) { if (sde_enc->cur_master && sde_enc->cur_master->ops.idle_pc_cache_display_status)
phys = sde_enc->phys_encs[i]; sde_enc->cur_master->ops.idle_pc_cache_display_status(sde_enc->cur_master);
if (phys && phys->ops.control_te)
phys->ops.control_te(phys, enable);
}
} }
static int _sde_encoder_input_connect(struct input_handler *handler, static int _sde_encoder_input_connect(struct input_handler *handler,
@@ -3022,7 +3038,7 @@ void sde_encoder_virt_restore(struct drm_encoder *drm_enc)
sde_enc->cur_master->ops.restore(sde_enc->cur_master); sde_enc->cur_master->ops.restore(sde_enc->cur_master);
_sde_encoder_virt_enable_helper(drm_enc); _sde_encoder_virt_enable_helper(drm_enc);
sde_encoder_control_te(drm_enc, true); sde_encoder_control_te(sde_enc, true);
/* /*
* During IPC misr ctl register is reset. * During IPC misr ctl register is reset.
@@ -3180,11 +3196,11 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
sizeof(sde_enc->cur_master->intf_cfg_v1)); sizeof(sde_enc->cur_master->intf_cfg_v1));
/* turn off vsync_in to update tear check configuration */ /* turn off vsync_in to update tear check configuration */
sde_encoder_control_te(drm_enc, false); sde_encoder_control_te(sde_enc, false);
sde_encoder_populate_encoder_phys(drm_enc, sde_enc, msm_mode); sde_encoder_populate_encoder_phys(drm_enc, sde_enc, msm_mode);
_sde_encoder_virt_enable_helper(drm_enc); _sde_encoder_virt_enable_helper(drm_enc);
sde_encoder_control_te(drm_enc, true); sde_encoder_control_te(sde_enc, true);
} }
void sde_encoder_virt_reset(struct drm_encoder *drm_enc) void sde_encoder_virt_reset(struct drm_encoder *drm_enc)

View File

@@ -396,11 +396,10 @@ bool sde_encoder_get_vblank_timestamp(struct drm_encoder *encoder,
ktime_t *tvblank); ktime_t *tvblank);
/** /**
* sde_encoder_control_te - control enabling/disabling VSYNC_IN_EN * sde_encoder_idle_pc_enter - control enable/disable VSYNC_IN_EN & cache display status at ipc
* @encoder: encoder pointer * @encoder: encoder pointer
* @enable: boolean to indicate enable/disable
*/ */
void sde_encoder_control_te(struct drm_encoder *encoder, bool enable); void sde_encoder_idle_pc_enter(struct drm_encoder *encoder);
/** /**
* sde_encoder_virt_restore - restore the encoder configs * sde_encoder_virt_restore - restore the encoder configs

View File

@@ -140,6 +140,7 @@ struct sde_encoder_virt_ops {
* count and underrun line count * count and underrun line count
* @add_to_minidump: Add this phys_enc data to minidumps * @add_to_minidump: Add this phys_enc data to minidumps
* @disable_autorefresh: Disable autorefresh * @disable_autorefresh: Disable autorefresh
* @idle_pc_cache_display_status: caches display status at idle power collapse
*/ */
struct sde_encoder_phys_ops { struct sde_encoder_phys_ops {
@@ -194,6 +195,7 @@ struct sde_encoder_phys_ops {
u32 (*get_underrun_line_count)(struct sde_encoder_phys *phys); u32 (*get_underrun_line_count)(struct sde_encoder_phys *phys);
void (*add_to_minidump)(struct sde_encoder_phys *phys); void (*add_to_minidump)(struct sde_encoder_phys *phys);
void (*disable_autorefresh)(struct sde_encoder_phys *phys); void (*disable_autorefresh)(struct sde_encoder_phys *phys);
void (*idle_pc_cache_display_status)(struct sde_encoder_phys *phys);
}; };
/** /**
@@ -275,6 +277,7 @@ struct sde_encoder_irq {
* @hw_dnsc_blur: Hardware interface to the downscale blur registers * @hw_dnsc_blur: Hardware interface to the downscale blur registers
* @sde_kms: Pointer to the sde_kms top level * @sde_kms: Pointer to the sde_kms top level
* @cached_mode: DRM mode cached at mode_set time, acted on in enable * @cached_mode: DRM mode cached at mode_set time, acted on in enable
* @wd_jitter : Pointer to watchdog jitter prams
* @enabled: Whether the encoder has enabled and running a mode * @enabled: Whether the encoder has enabled and running a mode
* @split_role: Role to play in a split-panel configuration * @split_role: Role to play in a split-panel configuration
* @intf_mode: Interface mode * @intf_mode: Interface mode
@@ -333,6 +336,7 @@ struct sde_encoder_phys {
struct sde_hw_dnsc_blur *hw_dnsc_blur; struct sde_hw_dnsc_blur *hw_dnsc_blur;
struct sde_kms *sde_kms; struct sde_kms *sde_kms;
struct drm_display_mode cached_mode; struct drm_display_mode cached_mode;
struct intf_wd_jitter_params wd_jitter;
enum sde_enc_split_role split_role; enum sde_enc_split_role split_role;
enum sde_intf_mode intf_mode; enum sde_intf_mode intf_mode;
enum sde_intf intf_idx; enum sde_intf intf_idx;

View File

@@ -2037,30 +2037,42 @@ 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, 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; u32 nominal_te_value;
struct sde_encoder_virt *sde_enc; struct sde_encoder_virt *sde_enc;
struct msm_mode_info *mode_info; struct msm_mode_info *mode_info;
const u32 multiplier = 1 << 10; const u32 multiplier = 1 << 10;
struct intf_wd_jitter_params wd_jtr;
sde_enc = to_sde_encoder_virt(phys_enc->parent); sde_enc = to_sde_encoder_virt(phys_enc->parent);
mode_info = &sde_enc->mode_info; mode_info = &sde_enc->mode_info;
if (mode_info->wd_jitter.jitter_type & MSM_DISPLAY_WD_INSTANTANEOUS_JITTER) 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, wd_jtr.jitter = mult_frac(multiplier,
mode_info->wd_jitter.inst_jitter_numer,
(mode_info->wd_jitter.inst_jitter_denom * 100)); (mode_info->wd_jitter.inst_jitter_denom * 100));
phys_enc->wd_jitter.jitter = wd_jtr.jitter;
}
if (mode_info->wd_jitter.jitter_type & MSM_DISPLAY_WD_LTJ_JITTER) { 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; 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, wd_jtr.ltj_max = mult_frac(nominal_te_value,
mode_info->wd_jitter.ltj_max_numer,
(mode_info->wd_jitter.ltj_max_denom) * 100); (mode_info->wd_jitter.ltj_max_denom) * 100);
wd_jitter->ltj_slope = mult_frac((1 << 16), wd_jitter->ltj_max, wd_jtr.ltj_slope = mult_frac((1 << 16), wd_jtr.ltj_max,
(mode_info->wd_jitter.ltj_time_sec * mode_info->frame_rate)); (mode_info->wd_jitter.ltj_time_sec * mode_info->frame_rate));
phys_enc->wd_jitter.ltj_max = wd_jtr.ltj_max;
phys_enc->wd_jitter.ltj_slope = wd_jtr.ltj_slope;
} }
phys_enc->hw_intf->ops.configure_wd_jitter(phys_enc->hw_intf, wd_jitter); phys_enc->hw_intf->ops.configure_wd_jitter(phys_enc->hw_intf, &phys_enc->wd_jitter);
}
static void sde_encoder_phys_cmd_store_ltj_values(struct sde_encoder_phys *phys_enc)
{
if (phys_enc && phys_enc->hw_intf->ops.get_wd_ltj_status)
phys_enc->hw_intf->ops.get_wd_ltj_status(phys_enc->hw_intf, &phys_enc->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,
@@ -2068,7 +2080,6 @@ static void sde_encoder_phys_cmd_setup_vsync_source(struct sde_encoder_phys *phy
{ {
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;
@@ -2083,7 +2094,7 @@ static void sde_encoder_phys_cmd_setup_vsync_source(struct sde_encoder_phys *phy
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) if (phys_enc->hw_intf->ops.configure_wd_jitter)
_sde_encoder_phys_cmd_calculate_wd_params(phys_enc, &wd_jitter); _sde_encoder_phys_cmd_calculate_wd_params(phys_enc);
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 {
@@ -2136,6 +2147,7 @@ static void sde_encoder_phys_cmd_init_ops(struct sde_encoder_phys_ops *ops)
ops->collect_misr = sde_encoder_helper_collect_misr; ops->collect_misr = sde_encoder_helper_collect_misr;
ops->add_to_minidump = sde_encoder_phys_cmd_add_enc_to_minidump; ops->add_to_minidump = sde_encoder_phys_cmd_add_enc_to_minidump;
ops->disable_autorefresh = _sde_encoder_phys_disable_autorefresh; ops->disable_autorefresh = _sde_encoder_phys_disable_autorefresh;
ops->idle_pc_cache_display_status = sde_encoder_phys_cmd_store_ltj_values;
} }
static inline bool sde_encoder_phys_cmd_intf_te_supported( static inline bool sde_encoder_phys_cmd_intf_te_supported(

View File

@@ -2493,6 +2493,7 @@ static int sde_intf_parse_dt(struct device_node *np,
set_bit(SDE_INTF_MDP_VSYNC_FC, &intf->features); set_bit(SDE_INTF_MDP_VSYNC_FC, &intf->features);
set_bit(SDE_INTF_TE_32BIT, &intf->features); set_bit(SDE_INTF_TE_32BIT, &intf->features);
set_bit(SDE_INTF_TE_SINGLE_UPDATE, &intf->features); set_bit(SDE_INTF_TE_SINGLE_UPDATE, &intf->features);
set_bit(SDE_INTF_WD_LTJ_CTL, &intf->features);
} }
} }

View File

@@ -606,6 +606,7 @@ enum {
* @SDE_INTF_MDP_VSYNC_FC INTF block has mdp vsync frame counter * @SDE_INTF_MDP_VSYNC_FC INTF block has mdp vsync frame counter
* @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_WD_JITTER INTF block has WD timer jitter support
* @SDE_INTF_WD_LTJ_CTL INTF block has WD long term jitter control support
* @SDE_INTF_MAX * @SDE_INTF_MAX
*/ */
enum { enum {
@@ -622,6 +623,7 @@ enum {
SDE_INTF_MDP_VSYNC_FC, SDE_INTF_MDP_VSYNC_FC,
SDE_INTF_AVR_STATUS, SDE_INTF_AVR_STATUS,
SDE_INTF_WD_JITTER, SDE_INTF_WD_JITTER,
SDE_INTF_WD_LTJ_CTL,
SDE_INTF_MAX SDE_INTF_MAX
}; };

View File

@@ -65,6 +65,8 @@
#define INTF_MISR_CTRL 0x180 #define INTF_MISR_CTRL 0x180
#define INTF_MISR_SIGNATURE 0x184 #define INTF_MISR_SIGNATURE 0x184
#define INTF_WD_TIMER_0_LTJ_CTL 0x200
#define INTF_WD_TIMER_0_LTJ_CTL1 0x204
#define INTF_VSYNC_TIMESTAMP_CTRL 0x210 #define INTF_VSYNC_TIMESTAMP_CTRL 0x210
#define INTF_VSYNC_TIMESTAMP0 0x214 #define INTF_VSYNC_TIMESTAMP0 0x214
#define INTF_VSYNC_TIMESTAMP1 0x218 #define INTF_VSYNC_TIMESTAMP1 0x218
@@ -76,6 +78,8 @@
#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
#define INTF_WD_TIMER_0_LTJ_INT_STATUS 0x240
#define INTF_WD_TIMER_0_LTJ_FRAC_STATUS 0x244
#define INTF_MUX 0x25C #define INTF_MUX 0x25C
#define INTF_UNDERRUN_COUNT 0x268 #define INTF_UNDERRUN_COUNT 0x268
#define INTF_STATUS 0x26C #define INTF_STATUS 0x26C
@@ -496,6 +500,40 @@ static void sde_hw_intf_configure_wd_timer_jitter(struct sde_hw_intf *intf,
if (wd_jitter->ltj_max) if (wd_jitter->ltj_max)
reg |= BIT(30); reg |= BIT(30);
SDE_REG_WRITE(c, INTF_WD_TIMER_0_JITTER_CTL, reg); SDE_REG_WRITE(c, INTF_WD_TIMER_0_JITTER_CTL, reg);
if (intf->cap->features & BIT(SDE_INTF_WD_LTJ_CTL)) {
if (wd_jitter->ltj_step_dir && wd_jitter->ltj_initial_val) {
reg = ((wd_jitter->ltj_step_dir & 0x1) << 31) |
(wd_jitter->ltj_initial_val & 0x1FFFFF);
SDE_REG_WRITE(c, INTF_WD_TIMER_0_LTJ_CTL, reg);
wd_jitter->ltj_step_dir = 0;
wd_jitter->ltj_initial_val = 0;
}
if (wd_jitter->ltj_fractional_val) {
SDE_REG_WRITE(c, INTF_WD_TIMER_0_LTJ_CTL1, wd_jitter->ltj_fractional_val);
wd_jitter->ltj_fractional_val = 0;
}
}
}
static void sde_hw_intf_read_wd_ltj_ctl(struct sde_hw_intf *intf,
struct intf_wd_jitter_params *wd_jitter)
{
struct sde_hw_blk_reg_map *c;
u32 reg;
c = &intf->hw;
if (intf->cap->features & BIT(SDE_INTF_WD_LTJ_CTL)) {
reg = SDE_REG_READ(c, INTF_WD_TIMER_0_LTJ_INT_STATUS);
wd_jitter->ltj_step_dir = reg & BIT(31);
wd_jitter->ltj_initial_val = (reg & 0x1FFFFF);
reg = SDE_REG_READ(c, INTF_WD_TIMER_0_LTJ_FRAC_STATUS);
wd_jitter->ltj_fractional_val = (reg & 0xFFFF);
}
} }
static void sde_hw_intf_setup_vsync_source(struct sde_hw_intf *intf, u32 frame_rate) static void sde_hw_intf_setup_vsync_source(struct sde_hw_intf *intf, u32 frame_rate)
@@ -1039,6 +1077,9 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
if (cap & BIT(SDE_INTF_WD_JITTER)) if (cap & BIT(SDE_INTF_WD_JITTER))
ops->configure_wd_jitter = sde_hw_intf_configure_wd_timer_jitter; ops->configure_wd_jitter = sde_hw_intf_configure_wd_timer_jitter;
if (cap & BIT(SDE_INTF_WD_LTJ_CTL))
ops->get_wd_ltj_status = sde_hw_intf_read_wd_ltj_ctl;
} }
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,

View File

@@ -73,13 +73,18 @@ struct intf_avr_params {
* jitter : max instantaneous jitter. * jitter : max instantaneous jitter.
* ltj_max : max long term jitter value. * ltj_max : max long term jitter value.
* ltj_slope : slope of long term jitter. * ltj_slope : slope of long term jitter.
*ltj_step_dir: direction of the step in LTJ
*ltj_initial_val: LTJ initial value
*ltj_fractional_val: LTJ fractional initial value
*/ */
struct intf_wd_jitter_params { struct intf_wd_jitter_params {
u32 jitter; u32 jitter;
u32 ltj_max; u32 ltj_max;
u32 ltj_slope; u32 ltj_slope;
u8 ltj_step_dir;
u32 ltj_initial_val;
u32 ltj_fractional_val;
}; };
/** /**
* struct sde_hw_intf_ops : Interface to the interface Hw driver functions * struct sde_hw_intf_ops : Interface to the interface Hw driver functions
* Assumption is these functions will be called after clocks are enabled * Assumption is these functions will be called after clocks are enabled
@@ -95,6 +100,8 @@ struct intf_wd_jitter_params {
* 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. * @configure_wd_jitter: Configure WD jitter.
* @ write_wd_ltj: Write WD long term jitter.
* @get_wd_ltj_status: Read WD long term jitter status.
* @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
*/ */
@@ -132,6 +139,10 @@ struct sde_hw_intf_ops {
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, void (*configure_wd_jitter)(struct sde_hw_intf *intf,
struct intf_wd_jitter_params *wd_jitter); struct intf_wd_jitter_params *wd_jitter);
void (*write_wd_ltj)(struct sde_hw_intf *intf,
struct intf_wd_jitter_params *wd_jitter);
void (*get_wd_ltj_status)(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,