Skip to content

Commit

Permalink
drm/tilcdc: Precalculate total frametime in tilcdc_crtc_set_mode()
Browse files Browse the repository at this point in the history
We need the total frame refresh time to check if we are too close to
vertical sync when updating the two framebuffer DMA registers and risk
a collision. This new method is more accurate that the previous that
based on mode's vrefresh value, which itself is inaccurate or may not
even be initialized.

Reported-by: Kevin Hao <kexin.hao@windriver.com>
Fixes: 11abbc9 ("drm/tilcdc: Set framebuffer DMA address to HW only if CRTC is enabled")
Cc: <stable@vger.kernel.org> # v4.11+
Signed-off-by: Jyri Sarha <jsarha@ti.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
  • Loading branch information
Jyri Sarha committed Oct 13, 2017
1 parent ba3fd95 commit ce99f72
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion drivers/gpu/drm/tilcdc/tilcdc_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/completion.h>
#include <linux/dma-mapping.h>
#include <linux/of_graph.h>
#include <linux/math64.h>

#include "tilcdc_drv.h"
#include "tilcdc_regs.h"
Expand All @@ -48,6 +49,7 @@ struct tilcdc_crtc {
unsigned int lcd_fck_rate;

ktime_t last_vblank;
unsigned int hvtotal_us;

struct drm_framebuffer *curr_fb;
struct drm_framebuffer *next_fb;
Expand Down Expand Up @@ -292,6 +294,12 @@ static void tilcdc_crtc_set_clk(struct drm_crtc *crtc)
LCDC_V2_CORE_CLK_EN);
}

uint tilcdc_mode_hvtotal(const struct drm_display_mode *mode)
{
return (uint) div_u64(1000llu * mode->htotal * mode->vtotal,
mode->clock);
}

static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
Expand Down Expand Up @@ -459,6 +467,9 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)
drm_framebuffer_get(fb);

crtc->hwmode = crtc->state->adjusted_mode;

tilcdc_crtc->hvtotal_us =
tilcdc_mode_hvtotal(&crtc->hwmode);
}

static void tilcdc_crtc_enable(struct drm_crtc *crtc)
Expand Down Expand Up @@ -642,7 +653,7 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);

next_vblank = ktime_add_us(tilcdc_crtc->last_vblank,
1000000 / crtc->hwmode.vrefresh);
tilcdc_crtc->hvtotal_us);
tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get()));

if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US)
Expand Down

0 comments on commit ce99f72

Please sign in to comment.