Commit aa1b0e59 authored by Rob Clark's avatar Rob Clark

drm/msm/mdp4: cursor fixes

It seems we need to update all cursor registers from vblank.  This
appears to be the cause of intermittent underflows when enabling/
disabling cursor.
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent b69720c0
...@@ -39,6 +39,7 @@ struct mdp4_crtc { ...@@ -39,6 +39,7 @@ struct mdp4_crtc {
spinlock_t lock; spinlock_t lock;
bool stale; bool stale;
uint32_t width, height; uint32_t width, height;
uint32_t x, y;
/* next cursor to scan-out: */ /* next cursor to scan-out: */
uint32_t next_iova; uint32_t next_iova;
...@@ -484,12 +485,12 @@ static int mdp4_crtc_set_property(struct drm_crtc *crtc, ...@@ -484,12 +485,12 @@ static int mdp4_crtc_set_property(struct drm_crtc *crtc,
static void update_cursor(struct drm_crtc *crtc) static void update_cursor(struct drm_crtc *crtc)
{ {
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
enum mdp4_dma dma = mdp4_crtc->dma; enum mdp4_dma dma = mdp4_crtc->dma;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
if (mdp4_crtc->cursor.stale) { if (mdp4_crtc->cursor.stale) {
struct mdp4_kms *mdp4_kms = get_kms(crtc);
struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo; struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo;
struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo; struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo;
uint32_t iova = mdp4_crtc->cursor.next_iova; uint32_t iova = mdp4_crtc->cursor.next_iova;
...@@ -521,6 +522,11 @@ static void update_cursor(struct drm_crtc *crtc) ...@@ -521,6 +522,11 @@ static void update_cursor(struct drm_crtc *crtc)
mdp4_crtc->cursor.scanout_bo = next_bo; mdp4_crtc->cursor.scanout_bo = next_bo;
mdp4_crtc->cursor.stale = false; mdp4_crtc->cursor.stale = false;
} }
mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma),
MDP4_DMA_CURSOR_POS_X(mdp4_crtc->cursor.x) |
MDP4_DMA_CURSOR_POS_Y(mdp4_crtc->cursor.y));
spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
} }
...@@ -572,6 +578,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, ...@@ -572,6 +578,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
drm_gem_object_unreference_unlocked(old_bo); drm_gem_object_unreference_unlocked(old_bo);
} }
crtc_flush(crtc);
request_pending(crtc, PENDING_CURSOR); request_pending(crtc, PENDING_CURSOR);
return 0; return 0;
...@@ -584,12 +591,15 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, ...@@ -584,12 +591,15 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{ {
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc); unsigned long flags;
enum mdp4_dma dma = mdp4_crtc->dma;
mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma), spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
MDP4_DMA_CURSOR_POS_X(x) | mdp4_crtc->cursor.x = x;
MDP4_DMA_CURSOR_POS_Y(y)); mdp4_crtc->cursor.y = y;
spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
crtc_flush(crtc);
request_pending(crtc, PENDING_CURSOR);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment