Commit e7bb4056 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'tilcdc-4.11-fixes' of https://github.com/jsarha/linux into drm-fixes

drm/tilcdc fixes for Linux v4.11

* tag 'tilcdc-4.11-fixes' of https://github.com/jsarha/linux:
  drm/tilcdc: Set framebuffer DMA address to HW only if CRTC is enabled
  drm/tilcdc: Fix hardcoded fail-return value in tilcdc_crtc_create()
parents 4495c08e 11abbc9f
...@@ -464,6 +464,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc) ...@@ -464,6 +464,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
unsigned long flags;
WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
mutex_lock(&tilcdc_crtc->enable_lock); mutex_lock(&tilcdc_crtc->enable_lock);
...@@ -484,7 +485,17 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc) ...@@ -484,7 +485,17 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG, tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG,
LCDC_PALETTE_LOAD_MODE(DATA_ONLY), LCDC_PALETTE_LOAD_MODE(DATA_ONLY),
LCDC_PALETTE_LOAD_MODE_MASK); LCDC_PALETTE_LOAD_MODE_MASK);
/* There is no real chance for a race here as the time stamp
* is taken before the raster DMA is started. The spin-lock is
* taken to have a memory barrier after taking the time-stamp
* and to avoid a context switch between taking the stamp and
* enabling the raster.
*/
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
tilcdc_crtc->last_vblank = ktime_get();
tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags);
drm_crtc_vblank_on(crtc); drm_crtc_vblank_on(crtc);
...@@ -539,7 +550,6 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown) ...@@ -539,7 +550,6 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)
} }
drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq);
tilcdc_crtc->last_vblank = 0;
tilcdc_crtc->enabled = false; tilcdc_crtc->enabled = false;
mutex_unlock(&tilcdc_crtc->enable_lock); mutex_unlock(&tilcdc_crtc->enable_lock);
...@@ -602,7 +612,6 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc, ...@@ -602,7 +612,6 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
{ {
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
unsigned long flags;
WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
...@@ -614,28 +623,30 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc, ...@@ -614,28 +623,30 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
drm_framebuffer_reference(fb); drm_framebuffer_reference(fb);
crtc->primary->fb = fb; crtc->primary->fb = fb;
tilcdc_crtc->event = event;
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); mutex_lock(&tilcdc_crtc->enable_lock);
if (crtc->hwmode.vrefresh && ktime_to_ns(tilcdc_crtc->last_vblank)) { if (tilcdc_crtc->enabled) {
unsigned long flags;
ktime_t next_vblank; ktime_t next_vblank;
s64 tdiff; s64 tdiff;
next_vblank = ktime_add_us(tilcdc_crtc->last_vblank, spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
1000000 / crtc->hwmode.vrefresh);
next_vblank = ktime_add_us(tilcdc_crtc->last_vblank,
1000000 / crtc->hwmode.vrefresh);
tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get())); tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get()));
if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US) if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US)
tilcdc_crtc->next_fb = fb; tilcdc_crtc->next_fb = fb;
} else
set_scanout(crtc, fb);
if (tilcdc_crtc->next_fb != fb)
set_scanout(crtc, fb);
tilcdc_crtc->event = event; spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags);
}
spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); mutex_unlock(&tilcdc_crtc->enable_lock);
return 0; return 0;
} }
...@@ -1036,5 +1047,5 @@ int tilcdc_crtc_create(struct drm_device *dev) ...@@ -1036,5 +1047,5 @@ int tilcdc_crtc_create(struct drm_device *dev)
fail: fail:
tilcdc_crtc_destroy(crtc); tilcdc_crtc_destroy(crtc);
return -ENOMEM; return ret;
} }
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