disp: msm: sde: add underrun line count information

Add underrun line count information for each underrun.

Change-Id: I34a740c33240fa8d444f4bbc3b8b014b0282fca1
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
This commit is contained in:
Dhaval Patel 2020-01-23 18:05:19 -08:00 committed by Gerrit - the friendly Code Review server
parent 9d96e47c53
commit 9438f3448b
5 changed files with 58 additions and 0 deletions

View File

@ -2887,12 +2887,16 @@ static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc,
static void sde_encoder_underrun_callback(struct drm_encoder *drm_enc, static void sde_encoder_underrun_callback(struct drm_encoder *drm_enc,
struct sde_encoder_phys *phy_enc) struct sde_encoder_phys *phy_enc)
{ {
struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
if (!phy_enc) if (!phy_enc)
return; return;
SDE_ATRACE_BEGIN("encoder_underrun_callback"); SDE_ATRACE_BEGIN("encoder_underrun_callback");
atomic_inc(&phy_enc->underrun_cnt); atomic_inc(&phy_enc->underrun_cnt);
SDE_EVT32(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt)); SDE_EVT32(DRMID(drm_enc), atomic_read(&phy_enc->underrun_cnt));
if (sde_enc->cur_master->ops.get_underrun_line_count)
sde_enc->cur_master->ops.get_underrun_line_count(
sde_enc->cur_master);
trace_sde_encoder_underrun(DRMID(drm_enc), trace_sde_encoder_underrun(DRMID(drm_enc),
atomic_read(&phy_enc->underrun_cnt)); atomic_read(&phy_enc->underrun_cnt));

View File

@ -133,6 +133,8 @@ struct sde_encoder_virt_ops {
* unitl transaction is complete. * unitl transaction is complete.
* @wait_for_active: Wait for display scan line to be in active area * @wait_for_active: Wait for display scan line to be in active area
* @setup_vsync_source: Configure vsync source selection for cmd mode. * @setup_vsync_source: Configure vsync source selection for cmd mode.
* @get_underrun_line_count: Obtain and log current internal vertical line
* count and underrun line count
*/ */
struct sde_encoder_phys_ops { struct sde_encoder_phys_ops {
@ -185,6 +187,7 @@ struct sde_encoder_phys_ops {
int (*wait_for_active)(struct sde_encoder_phys *phys); int (*wait_for_active)(struct sde_encoder_phys *phys);
void (*setup_vsync_source)(struct sde_encoder_phys *phys, void (*setup_vsync_source)(struct sde_encoder_phys *phys,
u32 vsync_source, bool is_dummy); u32 vsync_source, bool is_dummy);
u32 (*get_underrun_line_count)(struct sde_encoder_phys *phys);
}; };
/** /**

View File

@ -1174,6 +1174,33 @@ static int sde_encoder_phys_vid_get_line_count(
return phys_enc->hw_intf->ops.get_line_count(phys_enc->hw_intf); return phys_enc->hw_intf->ops.get_line_count(phys_enc->hw_intf);
} }
static u32 sde_encoder_phys_vid_get_underrun_line_count(
struct sde_encoder_phys *phys_enc)
{
u32 underrun_linecount = 0xebadebad;
struct intf_status intf_status = {0};
if (!phys_enc)
return -EINVAL;
if (!sde_encoder_phys_vid_is_master(phys_enc) || !phys_enc->hw_intf)
return -EINVAL;
if (phys_enc->hw_intf->ops.get_status)
phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf,
&intf_status);
if (phys_enc->hw_intf->ops.get_underrun_line_count)
underrun_linecount =
phys_enc->hw_intf->ops.get_underrun_line_count(
phys_enc->hw_intf);
SDE_EVT32(DRMID(phys_enc->parent), underrun_linecount,
intf_status.frame_count, intf_status.line_count);
return underrun_linecount;
}
static int sde_encoder_phys_vid_wait_for_active( static int sde_encoder_phys_vid_wait_for_active(
struct sde_encoder_phys *phys_enc) struct sde_encoder_phys *phys_enc)
{ {
@ -1268,6 +1295,8 @@ static void sde_encoder_phys_vid_init_ops(struct sde_encoder_phys_ops *ops)
ops->wait_dma_trigger = sde_encoder_phys_vid_wait_dma_trigger; ops->wait_dma_trigger = sde_encoder_phys_vid_wait_dma_trigger;
ops->wait_for_active = sde_encoder_phys_vid_wait_for_active; ops->wait_for_active = sde_encoder_phys_vid_wait_for_active;
ops->prepare_commit = sde_encoder_phys_vid_prepare_for_commit; ops->prepare_commit = sde_encoder_phys_vid_prepare_for_commit;
ops->get_underrun_line_count =
sde_encoder_phys_vid_get_underrun_line_count;
} }
struct sde_encoder_phys *sde_encoder_phys_vid_init( struct sde_encoder_phys *sde_encoder_phys_vid_init(

View File

@ -62,6 +62,7 @@
#define INTF_MISR_SIGNATURE 0x184 #define INTF_MISR_SIGNATURE 0x184
#define INTF_MUX 0x25C #define INTF_MUX 0x25C
#define INTF_UNDERRUN_COUNT 0x268
#define INTF_STATUS 0x26C #define INTF_STATUS 0x26C
#define INTF_AVR_CONTROL 0x270 #define INTF_AVR_CONTROL 0x270
#define INTF_AVR_MODE 0x274 #define INTF_AVR_MODE 0x274
@ -484,6 +485,23 @@ static u32 sde_hw_intf_get_line_count(struct sde_hw_intf *intf)
return SDE_REG_READ(c, INTF_LINE_COUNT); return SDE_REG_READ(c, INTF_LINE_COUNT);
} }
static u32 sde_hw_intf_get_underrun_line_count(struct sde_hw_intf *intf)
{
struct sde_hw_blk_reg_map *c;
u32 hsync_period;
if (!intf)
return 0;
c = &intf->hw;
hsync_period = SDE_REG_READ(c, INTF_HSYNC_CTL);
hsync_period = ((hsync_period & 0xffff0000) >> 16);
return hsync_period ?
SDE_REG_READ(c, INTF_UNDERRUN_COUNT) / hsync_period :
0xebadebad;
}
static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf, static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf,
struct sde_hw_tear_check *te) struct sde_hw_tear_check *te)
{ {
@ -695,6 +713,7 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
ops->setup_misr = sde_hw_intf_setup_misr; ops->setup_misr = sde_hw_intf_setup_misr;
ops->collect_misr = sde_hw_intf_collect_misr; ops->collect_misr = sde_hw_intf_collect_misr;
ops->get_line_count = sde_hw_intf_get_line_count; ops->get_line_count = sde_hw_intf_get_line_count;
ops->get_underrun_line_count = sde_hw_intf_get_underrun_line_count;
ops->avr_setup = sde_hw_intf_avr_setup; ops->avr_setup = sde_hw_intf_avr_setup;
ops->avr_trigger = sde_hw_intf_avr_trigger; ops->avr_trigger = sde_hw_intf_avr_trigger;
ops->avr_ctrl = sde_hw_intf_avr_ctrl; ops->avr_ctrl = sde_hw_intf_avr_ctrl;

View File

@ -68,6 +68,8 @@ struct intf_avr_params {
* @ setup_misr: enables/disables MISR in HW register * @ setup_misr: enables/disables MISR in HW register
* @ collect_misr: reads and stores MISR data from HW register * @ collect_misr: reads and stores MISR data from HW register
* @ get_line_count: reads current vertical line counter * @ get_line_count: reads current vertical line counter
* @ get_underrun_line_count: reads current underrun pixel clock count and
* converts it into line count
* @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
*/ */
@ -100,6 +102,7 @@ struct sde_hw_intf_ops {
* is used for command mode panels * is used for command mode panels
*/ */
u32 (*get_line_count)(struct sde_hw_intf *intf); u32 (*get_line_count)(struct sde_hw_intf *intf);
u32 (*get_underrun_line_count)(struct sde_hw_intf *intf);
void (*bind_pingpong_blk)(struct sde_hw_intf *intf, void (*bind_pingpong_blk)(struct sde_hw_intf *intf,
bool enable, bool enable,