gpu: nvgpu: increase delays in do_idle()
Deepak Nibade [Thu, 3 Jul 2014 15:18:30 +0000 (20:18 +0530)]
Increase the wait delays in do_idle() to 2000 mS and make use
of msleep instead of mdelays

Also, to check if GPU is rail gated or not, add a do-while()
loop which will keep checking the status and bail out as soon
as GPU is rail gated

This increase in delays is required to allow GPU sufficient
time to complete its work and get rail gated

These delays are specially needed during stress testing where
it is possible that a large amount of GPU work is blocked
during do_idle() and then it might take more time to complete
it while next do_idle() is waiting for it

Also, remove waiting on API gk20a_wait_channel_idle() for each
channels since it is sufficient to wait for refcount to be 1

bug 1529160

Change-Id: Ie541485fbdda76d79ae4a75dda928da240fc5d8f
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/434192
GVS: Gerrit_Virtual_Submit
Reviewed-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>

drivers/gpu/nvgpu/gk20a/gk20a.c

index 74138e3..bf882f2 100644 (file)
@@ -76,6 +76,8 @@ u32 gk20a_dbg_mask = GK20A_DEFAULT_DBG_MASK;
 u32 gk20a_dbg_ftrace;
 #endif
 
+#define GK20A_WAIT_FOR_IDLE_MS 2000
+
 static int gk20a_pm_finalize_poweron(struct device *dev);
 static int gk20a_pm_prepare_poweroff(struct device *dev);
 
@@ -1618,9 +1620,10 @@ int gk20a_do_idle(void)
                NULL, "gk20a.0"));
        struct gk20a *g = get_gk20a(pdev);
        struct gk20a_platform *platform = dev_get_drvdata(&pdev->dev);
-       struct fifo_gk20a *f = &g->fifo;
-       unsigned long timeout = jiffies + msecs_to_jiffies(200);
-       int chid, ref_cnt;
+       unsigned long timeout = jiffies +
+               msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS);
+       int ref_cnt;
+       bool is_railgated;
 
        if (!platform->can_railgate)
                return -ENOSYS;
@@ -1641,12 +1644,8 @@ int gk20a_do_idle(void)
        /* check and wait until GPU is idle (with a timeout) */
        pm_runtime_barrier(&pdev->dev);
 
-       for (chid = 0; chid < f->num_channels; chid++)
-               if (gk20a_wait_channel_idle(&f->channel[chid]))
-                       goto fail;
-
        do {
-               mdelay(1);
+               msleep(1);
                ref_cnt = atomic_read(&pdev->dev.power.usage_count);
        } while (ref_cnt != 1 && time_before(jiffies, timeout));
 
@@ -1660,19 +1659,20 @@ int gk20a_do_idle(void)
        pm_runtime_put_sync(&pdev->dev);
 
        /* add sufficient delay to allow GPU to rail gate */
-       mdelay(platform->railgate_delay);
+       msleep(platform->railgate_delay);
 
-       if (platform->is_railgated(pdev))
-               return 0;
-       else {
-               /* wait for some more time */
-               mdelay(100);
-               if (platform->is_railgated(pdev))
-                       return 0;
-       }
+       timeout = jiffies + msecs_to_jiffies(GK20A_WAIT_FOR_IDLE_MS);
+
+       /* check in loop if GPU is railgated or not */
+       do {
+               msleep(1);
+               is_railgated = platform->is_railgated(pdev);
+       } while (!is_railgated && time_before(jiffies, timeout));
 
-       /* GPU is not rail gated by now, return error */
-       goto fail_timeout;
+       if (is_railgated)
+               return 0;
+       else
+               goto fail_timeout;
 
 fail:
        pm_runtime_put_noidle(&pdev->dev);