disp: msm: sde: switch to WD vsync on unexpected panel jitter

Switch to watchdog vsync whenever panel jitter is
identified during frame-transfer on command mode display.
This would allow the HW to finish processing the frame
with watchdog vsync source. Switch back to default vsync
source after the frame-transfer is complete. This would
help in the MDP hang issues in panels that generate TEs
with thresholds greater than the projected jitter.

Change-Id: Ic3fa78d90e7f44cb0186857716ac27e72505fd32
Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
This commit is contained in:
Veera Sundaram Sankaran
2019-09-26 19:31:25 -07:00
parent 9e60a4854b
commit fb54f6e6e7
3 changed files with 186 additions and 30 deletions

View File

@@ -25,6 +25,7 @@
#define KICKOFF_TIMEOUT_MS 84
#define KICKOFF_TIMEOUT_JIFFIES msecs_to_jiffies(KICKOFF_TIMEOUT_MS)
#define MAX_TE_PROFILE_COUNT 5
/**
* enum sde_enc_split_role - Role this physical encoder will play in a
* split-panel configuration, where one panel is master, and others slaves.
@@ -361,6 +362,17 @@ struct sde_encoder_phys_cmd_autorefresh {
wait_queue_head_t kickoff_wq;
};
/**
* struct sde_encoder_phys_cmd_te_timestamp - list node to keep track of
* rd_ptr/TE timestamp
* @list: list node
* @timestamp: TE timestamp
*/
struct sde_encoder_phys_cmd_te_timestamp {
struct list_head list;
ktime_t timestamp;
};
/**
* struct sde_encoder_phys_cmd - sub-class of sde_encoder_phys to handle command
* mode specific operations
@@ -371,6 +383,8 @@ struct sde_encoder_phys_cmd_autorefresh {
* @pending_vblank_cnt: Atomic counter tracking pending wait for VBLANK
* @pending_vblank_wq: Wait queue for blocking until VBLANK received
* @wr_ptr_wait_success: log wr_ptr_wait success for release fence trigger
* @te_timestamp_list: List head for the TE timestamp list
* @te_timestamp: Array of size MAX_TE_PROFILE_COUNT te_timestamp_list elements
*/
struct sde_encoder_phys_cmd {
struct sde_encoder_phys base;
@@ -380,6 +394,9 @@ struct sde_encoder_phys_cmd {
atomic_t pending_vblank_cnt;
wait_queue_head_t pending_vblank_wq;
bool wr_ptr_wait_success;
struct list_head te_timestamp_list;
struct sde_encoder_phys_cmd_te_timestamp
te_timestamp[MAX_TE_PROFILE_COUNT];
};
/**
@@ -558,6 +575,21 @@ int sde_encoder_helper_wait_event_timeout(
int32_t hw_id,
struct sde_encoder_wait_info *info);
/*
* sde_encoder_get_fps - get the allowed panel jitter in nanoseconds
* @encoder: Pointer to drm encoder object
*/
void sde_encoder_helper_get_jitter_bounds_ns(struct drm_encoder *encoder,
u64 *l_bound, u64 *u_bound);
/**
* sde_encoder_helper_switch_vsync - switch vsync source to WD or default
* @drm_enc: Pointer to drm encoder structure
* @watchdog_te: switch vsync source to watchdog TE
*/
int sde_encoder_helper_switch_vsync(struct drm_encoder *drm_enc,
bool watchdog_te);
/**
* sde_encoder_helper_hw_reset - issue ctl hw reset
* This helper function may be optionally specified by physical