mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
rk fb: add get frame time interface that is used for ddr change
This commit is contained in:
@@ -1271,7 +1271,7 @@ static int rk3288_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
|
||||
val = v_FS_INTR_CLR(1) | v_FS_INTR_EN(1) | v_LINE_FLAG_INTR_CLR(1) |
|
||||
v_LINE_FLAG_INTR_EN(1) | v_BUS_ERROR_INTR_CLR(1) | v_BUS_ERROR_INTR_EN(0) |
|
||||
v_DSP_LINE_FLAG_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
|
||||
screen->mode.yres -1);
|
||||
screen->mode.yres);
|
||||
lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
|
||||
#if 0
|
||||
mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN | m_WIN2_EMPTY_INTR_EN |
|
||||
@@ -3093,6 +3093,9 @@ int rk3288_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
|
||||
if (lcdc_dev->clk_on &&(!dev_drv->suspend_flag)){
|
||||
int_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
|
||||
if (int_reg & m_LINE_FLAG_INTR_STS) {
|
||||
lcdc_dev->driver.frame_time.last_framedone_t =
|
||||
lcdc_dev->driver.frame_time.framedone_t;
|
||||
lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
|
||||
lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
|
||||
v_LINE_FLAG_INTR_CLR(1));
|
||||
ret = RK_LF_STATUS_FC;
|
||||
@@ -3445,6 +3448,7 @@ static irqreturn_t rk3288_lcdc_isr(int irq, void *dev_id)
|
||||
(struct lcdc_device *)dev_id;
|
||||
ktime_t timestamp = ktime_get();
|
||||
u32 intr0_reg;
|
||||
|
||||
intr0_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
|
||||
|
||||
if(intr0_reg & m_FS_INTR_STS){
|
||||
@@ -3464,6 +3468,9 @@ static irqreturn_t rk3288_lcdc_isr(int irq, void *dev_id)
|
||||
wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
|
||||
|
||||
}else if(intr0_reg & m_LINE_FLAG_INTR_STS){
|
||||
lcdc_dev->driver.frame_time.last_framedone_t =
|
||||
lcdc_dev->driver.frame_time.framedone_t;
|
||||
lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
|
||||
lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
|
||||
v_LINE_FLAG_INTR_CLR(1));
|
||||
}else if(intr0_reg & m_BUS_ERROR_INTR_STS){
|
||||
|
||||
@@ -512,27 +512,75 @@ static struct rk_lcdc_driver *rk_get_prmry_lcdc_drv(void)
|
||||
return dev_drv;
|
||||
}
|
||||
|
||||
int rk_fb_get_prmry_screen_ft(void)
|
||||
/*
|
||||
* get one frame time of the prmry screen, unit: us
|
||||
*/
|
||||
u32 rk_fb_get_prmry_screen_ft(void)
|
||||
{
|
||||
struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv();
|
||||
uint32_t htotal, vtotal, pix_total, ft_us, pixclock_ns;
|
||||
uint32_t htotal, vtotal, pixclock_ps;
|
||||
u64 pix_total, ft_us;
|
||||
|
||||
if (unlikely(!dev_drv))
|
||||
return 0;
|
||||
|
||||
pixclock_ns = dev_drv->pixclock / 1000;
|
||||
pixclock_ps = dev_drv->pixclock;
|
||||
|
||||
htotal = (dev_drv->cur_screen->mode.upper_margin +
|
||||
vtotal = (dev_drv->cur_screen->mode.upper_margin +
|
||||
dev_drv->cur_screen->mode.lower_margin +
|
||||
dev_drv->cur_screen->mode.yres +
|
||||
dev_drv->cur_screen->mode.vsync_len);
|
||||
vtotal = (dev_drv->cur_screen->mode.left_margin +
|
||||
htotal = (dev_drv->cur_screen->mode.left_margin +
|
||||
dev_drv->cur_screen->mode.right_margin +
|
||||
dev_drv->cur_screen->mode.xres +
|
||||
dev_drv->cur_screen->mode.hsync_len);
|
||||
pix_total = htotal * vtotal / 1000;
|
||||
ft_us = pix_total * pixclock_ns;
|
||||
return ft_us;
|
||||
pix_total = htotal * vtotal;
|
||||
ft_us = pix_total * pixclock_ps;
|
||||
do_div(ft_us, 1000000);
|
||||
if (dev_drv->frame_time.ft == 0)
|
||||
dev_drv->frame_time.ft = ft_us;
|
||||
|
||||
ft_us = dev_drv->frame_time.framedone_t - dev_drv->frame_time.last_framedone_t;
|
||||
do_div(ft_us, 1000);
|
||||
dev_drv->frame_time.ft = min(dev_drv->frame_time.ft, ft_us);
|
||||
return dev_drv->frame_time.ft;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the vblanking time of the prmry screen, unit: us
|
||||
*/
|
||||
u32 rk_fb_get_prmry_screen_vbt(void)
|
||||
{
|
||||
struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv();
|
||||
uint32_t htotal, vblank, pixclock_ps;
|
||||
u64 pix_blank, vbt_us;
|
||||
|
||||
if (unlikely(!dev_drv))
|
||||
return 0;
|
||||
|
||||
pixclock_ps = dev_drv->pixclock;
|
||||
|
||||
htotal = (dev_drv->cur_screen->mode.left_margin +
|
||||
dev_drv->cur_screen->mode.right_margin +
|
||||
dev_drv->cur_screen->mode.xres +
|
||||
dev_drv->cur_screen->mode.hsync_len);
|
||||
vblank = (dev_drv->cur_screen->mode.upper_margin +
|
||||
dev_drv->cur_screen->mode.lower_margin +
|
||||
dev_drv->cur_screen->mode.vsync_len);
|
||||
pix_blank = htotal * vblank;
|
||||
vbt_us = pix_blank * pixclock_ps;
|
||||
do_div(vbt_us, 1000000);
|
||||
return (u32)vbt_us;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the frame done time of the prmry screen, unit: us
|
||||
*/
|
||||
u64 rk_fb_get_prmry_screen_framedone_t(void)
|
||||
{
|
||||
struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv();
|
||||
|
||||
return dev_drv->frame_time.framedone_t;
|
||||
}
|
||||
|
||||
static struct rk_lcdc_driver *rk_get_extend_lcdc_drv(void)
|
||||
@@ -591,12 +639,10 @@ bool rk_fb_poll_wait_frame_complete(void)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!(rk_fb_poll_prmry_screen_vblank() == RK_LF_STATUS_FR) && --timeout)
|
||||
;
|
||||
while (!(rk_fb_poll_prmry_screen_vblank() == RK_LF_STATUS_FC) && --timeout)
|
||||
;
|
||||
|
||||
if (likely(dev_drv)) {
|
||||
if (dev_drv->ops->set_irq_to_cpu)
|
||||
dev_drv->ops->set_irq_to_cpu(dev_drv, 1);
|
||||
|
||||
@@ -103,7 +103,9 @@ extern struct ion_client *rockchip_ion_client_create(const char * name);
|
||||
#endif
|
||||
|
||||
extern int rk_fb_poll_prmry_screen_vblank(void);
|
||||
extern int rk_fb_get_prmry_screen_ft(void);
|
||||
extern u32 rk_fb_get_prmry_screen_ft(void);
|
||||
extern u32 rk_fb_get_prmry_screen_vbt(void);
|
||||
extern u64 rk_fb_get_prmry_screen_framedone_t(void);
|
||||
extern bool rk_fb_poll_wait_frame_complete(void);
|
||||
|
||||
/********************************************************************
|
||||
@@ -242,6 +244,12 @@ struct rk_fb_rgb {
|
||||
struct fb_bitfield transp;
|
||||
};
|
||||
|
||||
struct rk_fb_frame_time {
|
||||
u64 last_framedone_t;
|
||||
u64 framedone_t;
|
||||
u32 ft;
|
||||
};
|
||||
|
||||
struct rk_fb_vsync {
|
||||
wait_queue_head_t wait;
|
||||
ktime_t timestamp;
|
||||
@@ -533,6 +541,7 @@ struct rk_lcdc_driver {
|
||||
spinlock_t cpl_lock; //lock for completion frame done
|
||||
int first_frame;
|
||||
struct rk_fb_vsync vsync_info;
|
||||
struct rk_fb_frame_time frame_time;
|
||||
int wait_fs; //wait for new frame start in kernel
|
||||
struct sw_sync_timeline *timeline;
|
||||
int timeline_max;
|
||||
|
||||
Reference in New Issue
Block a user