[PATCH] drm/msm: change to uninterruptible wait in atomic commit

2015-06-22 Thread Wentao Xu
The atomic commit cannot easily undo and return an error once the
state is swapped. Change to uninterruptible wait, and ignore the
timeout error.

Signed-off-by: Wentao Xu 
---
 drivers/gpu/drm/msm/msm_atomic.c |  8 ++--
 drivers/gpu/drm/msm/msm_drv.c| 13 +
 drivers/gpu/drm/msm/msm_drv.h|  4 ++--
 drivers/gpu/drm/msm/msm_gem.c|  2 +-
 4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 8763918..4386352 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -257,12 +257,8 @@ int msm_atomic_commit(struct drm_device *dev,

timeout = ktime_add(ktime_get(), ms_to_ktime(1000));

-   ret = msm_wait_fence_interruptable(dev, c->fence, );
-   if (ret) {
-   WARN_ON(ret);  // TODO unswap state back?  or??
-   commit_destroy(c);
-   return ret;
-   }
+   /* uninterruptible wait */
+   msm_wait_fence(dev, c->fence, , false);

complete_commit(c);

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 29af5ba..c445522 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -637,8 +637,8 @@ static void msm_debugfs_cleanup(struct drm_minor *minor)
  * Fences:
  */

-int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
-   ktime_t *timeout)
+int msm_wait_fence(struct drm_device *dev, uint32_t fence,
+   ktime_t *timeout , bool interruptible)
 {
struct msm_drm_private *priv = dev->dev_private;
int ret;
@@ -667,7 +667,12 @@ int msm_wait_fence_interruptable(struct drm_device *dev, 
uint32_t fence,
remaining_jiffies = timespec_to_jiffies();
}

-   ret = wait_event_interruptible_timeout(priv->fence_event,
+   if (interruptible)
+   ret = 
wait_event_interruptible_timeout(priv->fence_event,
+   fence_completed(dev, fence),
+   remaining_jiffies);
+   else
+   ret = wait_event_timeout(priv->fence_event,
fence_completed(dev, fence),
remaining_jiffies);

@@ -850,7 +855,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, 
void *data,
return -EINVAL;
}

-   return msm_wait_fence_interruptable(dev, args->fence, );
+   return msm_wait_fence(dev, args->fence, , true);
 }

 static const struct drm_ioctl_desc msm_ioctls[] = {
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index e7c5ea1..4ff0ec9 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -164,8 +164,8 @@ int msm_atomic_commit(struct drm_device *dev,

 int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu);

-int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
-   ktime_t *timeout);
+int msm_wait_fence(struct drm_device *dev, uint32_t fence,
+   ktime_t *timeout, bool interruptible);
 int msm_queue_fence_cb(struct drm_device *dev,
struct msm_fence_cb *cb, uint32_t fence);
 void msm_update_fence(struct drm_device *dev, uint32_t fence);
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 9b62201..e73d465 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -460,7 +460,7 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t 
op, ktime_t *timeout)
if (op & MSM_PREP_NOSYNC)
timeout = NULL;

-   ret = msm_wait_fence_interruptable(dev, fence, timeout);
+   ret = msm_wait_fence(dev, fence, timeout, true);
}

/* TODO cache maintenance */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



[PATCH] drm/msm/mdp5: release SMB(shared memory blocks) in various cases

2015-06-19 Thread Wentao Xu
Release all blocks after the pipe is disabled, even when vsync
didn't happen in some error cases. Allow requesting SMB multiple
times before configuring to hardware, by releasing blocks not
programmed to hardware yet for shrinking case.

Signed-off-by: Wentao Xu 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c   | 13 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h   |  2 +
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 33 +---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c   | 87 ++-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h   |  1 +
 5 files changed, 104 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 97226a1..db49ee8 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -78,7 +78,20 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct 
drm_atomic_state *st

 static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state 
*state)
 {
+   int i;
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+   int nplanes = mdp5_kms->dev->mode_config.num_total_plane;
+
+   for (i = 0; i < nplanes; i++) {
+   struct drm_plane *plane = state->planes[i];
+   struct drm_plane_state *plane_state = state->plane_states[i];
+
+   if (!plane)
+   continue;
+
+   mdp5_plane_complete_commit(plane, plane_state);
+   }
+
mdp5_disable(mdp5_kms);
 }

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 2c0de17..42f270b 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -227,6 +227,8 @@ void mdp5_plane_install_properties(struct drm_plane *plane,
struct drm_mode_object *obj);
 uint32_t mdp5_plane_get_flush(struct drm_plane *plane);
 void mdp5_plane_complete_flip(struct drm_plane *plane);
+void mdp5_plane_complete_commit(struct drm_plane *plane,
+   struct drm_plane_state *state);
 enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane);
 struct drm_plane *mdp5_plane_init(struct drm_device *dev,
enum mdp5_pipe pipe, bool private_plane, uint32_t reg_offset);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 18a3d20..05b2634 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -31,8 +31,6 @@ struct mdp5_plane {

uint32_t nformats;
uint32_t formats[32];
-
-   bool enabled;
 };
 #define to_mdp5_plane(x) container_of(x, struct mdp5_plane, base)

@@ -56,22 +54,6 @@ static bool plane_enabled(struct drm_plane_state *state)
return state->fb && state->crtc;
 }

-static int mdp5_plane_disable(struct drm_plane *plane)
-{
-   struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
-   struct mdp5_kms *mdp5_kms = get_kms(plane);
-   enum mdp5_pipe pipe = mdp5_plane->pipe;
-
-   DBG("%s: disable", mdp5_plane->name);
-
-   if (mdp5_kms) {
-   /* Release the memory we requested earlier from the SMP: */
-   mdp5_smp_release(mdp5_kms->smp, pipe);
-   }
-
-   return 0;
-}
-
 static void mdp5_plane_destroy(struct drm_plane *plane)
 {
struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
@@ -224,7 +206,6 @@ static void mdp5_plane_atomic_update(struct drm_plane 
*plane,

if (!plane_enabled(state)) {
to_mdp5_plane_state(state)->pending = true;
-   mdp5_plane_disable(plane);
} else if (to_mdp5_plane_state(state)->mode_changed) {
int ret;
to_mdp5_plane_state(state)->pending = true;
@@ -602,6 +583,20 @@ uint32_t mdp5_plane_get_flush(struct drm_plane *plane)
return mdp5_plane->flush_mask;
 }

+/* called after vsync in thread context */
+void mdp5_plane_complete_commit(struct drm_plane *plane,
+   struct drm_plane_state *state)
+{
+   struct mdp5_kms *mdp5_kms = get_kms(plane);
+   struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
+   enum mdp5_pipe pipe = mdp5_plane->pipe;
+
+   if (!plane_enabled(plane->state)) {
+   DBG("%s: free SMP", mdp5_plane->name);
+   mdp5_smp_release(mdp5_kms->smp, pipe);
+   }
+}
+
 /* initialize plane */
 struct drm_plane *mdp5_plane_init(struct drm_device *dev,
enum mdp5_pipe pipe, bool private_plane, uint32_t reg_offset)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
index 16702ae..64a27d8 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
@@ -34,22 +34,44 @@
  * and CANNOT be re-allocated (eg: MMB0 and MMB1 both tied to RGB0).
  *
  * For each block that can be dynamically allocated, it can be