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:
parent
9d96e47c53
commit
9438f3448b
@ -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));
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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(
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user