diff options
| author | Rob Clark <robdclark@gmail.com> | 2017-02-10 15:36:33 -0500 |
|---|---|---|
| committer | Sushmita Susheelendra <ssusheel@codeaurora.org> | 2017-09-07 15:02:35 -0600 |
| commit | d223bc2236d8b919d46e2dbf5043bade76c91abc (patch) | |
| tree | d5f71fc20c88f0c561ab87292936d99d0fe8ac7e /drivers/gpu/drm | |
| parent | aa450b1d93dbc7cb7b069d3f2672c4889a5b0c58 (diff) | |
drm/msm/gpu: use pm-runtime
We need to use pm-runtime properly when IOMMU is using device_link() to
control it's own clocks.
Change-Id: I7c5668e6a0fcfc2d4664355e49c49d4dcb26323e
Signed-off-by: Rob Clark <robdclark@gmail.com>
Git-commit: eeb754746b140c5f55e6b25706a9142aa549b348
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
[ssusheel@codeaurora.org: fix some merge conflicts]
Signed-off-by: Sushmita Susheelendra <ssusheel@codeaurora.org>
Diffstat (limited to 'drivers/gpu/drm')
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 69 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_device.c | 36 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.c | 117 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.h | 12 |
8 files changed, 96 insertions, 177 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index c085e173232b..049478fd9bcb 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -406,11 +406,9 @@ static const unsigned int a3xx_registers[] = { #ifdef CONFIG_DEBUG_FS static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m) { - gpu->funcs->pm_resume(gpu); seq_printf(m, "status: %08x\n", gpu_read(gpu, REG_A3XX_RBBM_STATUS)); adreno_show(gpu, m); - gpu->funcs->pm_suspend(gpu); } #endif diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 624c2a87d593..45c83fbe20e1 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -443,13 +443,9 @@ static const unsigned int a4xx_registers[] = { #ifdef CONFIG_DEBUG_FS static void a4xx_show(struct msm_gpu *gpu, struct seq_file *m) { - gpu->funcs->pm_resume(gpu); - seq_printf(m, "status: %08x\n", gpu_read(gpu, REG_A4XX_RBBM_STATUS)); - adreno_show(gpu, m); - gpu->funcs->pm_suspend(gpu); } #endif diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 765c1c087c76..886c728788b6 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -15,7 +15,6 @@ #include "msm_iommu.h" #include "msm_trace.h" #include "a5xx_gpu.h" -#include <linux/clk/msm-clk.h> #define SECURE_VA_START 0xc0000000 #define SECURE_VA_SIZE SZ_256M @@ -1170,26 +1169,11 @@ static int a5xx_pm_resume(struct msm_gpu *gpu) { int ret; - /* - * Between suspend/resumes the GPU clocks need to be turned off - * but not a complete power down, typically between frames. Set the - * memory retention flags on the GPU core clock to retain memory - * across clock toggles. - */ - if (gpu->core_clk) { - clk_set_flags(gpu->core_clk, CLKFLAG_RETAIN_PERIPH); - clk_set_flags(gpu->core_clk, CLKFLAG_RETAIN_MEM); - } - /* Turn on the core power */ ret = msm_gpu_pm_resume(gpu); if (ret) return ret; - /* If we are already up, don't mess with what works */ - if (gpu->active_cnt > 1) - return 0; - /* Turn the RBCCU domain first to limit the chances of voltage droop */ gpu_write(gpu, REG_A5XX_GPMU_RBCCU_POWER_CNTL, 0x778000); @@ -1220,33 +1204,23 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - /* Turn off the memory retention flag when not necessary */ - if (gpu->core_clk) { - clk_set_flags(gpu->core_clk, CLKFLAG_NORETAIN_PERIPH); - clk_set_flags(gpu->core_clk, CLKFLAG_NORETAIN_MEM); - } - - /* Only do this next bit if we are about to go down */ - if (gpu->active_cnt == 1) { - /* Clear the VBIF pipe before shutting down */ - - gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0xF); - spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) & 0xF) + /* Clear the VBIF pipe before shutting down */ + gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0xF); + spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) & 0xF) == 0xF); - gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0); + gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0); - /* - * Reset the VBIF before power collapse to avoid issue with FIFO - * entries - */ - if (adreno_is_a530(adreno_gpu)) { - /* These only need to be done for A530 */ - gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, + /* + * Reset the VBIF before power collapse to avoid issue with FIFO + * entries + */ + if (adreno_is_a530(adreno_gpu)) { + /* These only need to be done for A530 */ + gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C0000); - gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, + gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x00000000); - } } return msm_gpu_pm_suspend(gpu); @@ -1266,29 +1240,10 @@ static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) #ifdef CONFIG_DEBUG_FS static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m) { - struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); - bool enabled = test_bit(A5XX_HWCG_ENABLED, &a5xx_gpu->flags); - - gpu->funcs->pm_resume(gpu); - seq_printf(m, "status: %08x\n", gpu_read(gpu, REG_A5XX_RBBM_STATUS)); - - /* - * Temporarily disable hardware clock gating before going into - * adreno_show to avoid issues while reading the registers - */ - - if (enabled) - a5xx_set_hwcg(gpu, false); - adreno_show(gpu, m); - if (enabled) - a5xx_set_hwcg(gpu, true); - - gpu->funcs->pm_suspend(gpu); } #endif diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 4e4709d6172f..0415a65b0e72 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -164,13 +164,10 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) if (gpu) { int ret; - mutex_lock(&dev->struct_mutex); - gpu->funcs->pm_resume(gpu); - mutex_unlock(&dev->struct_mutex); - disable_irq(gpu->irq); - - ret = gpu->funcs->hw_init(gpu); + pm_runtime_get_sync(&pdev->dev); + ret = msm_gpu_hw_init(gpu); + pm_runtime_put_sync(&pdev->dev); if (ret) { dev_err(dev->dev, "gpu hw init failed: %d\n", ret); mutex_lock(&dev->struct_mutex); @@ -178,10 +175,6 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); gpu->funcs->destroy(gpu); gpu = NULL; - } else { - enable_irq(gpu->irq); - /* give inactive pm a chance to kick in: */ - msm_gpu_retire(gpu); } } @@ -250,12 +243,35 @@ static const struct of_device_id dt_match[] = { {} }; +#ifdef CONFIG_PM +static int adreno_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct msm_gpu *gpu = platform_get_drvdata(pdev); + + return gpu->funcs->pm_resume(gpu); +} + +static int adreno_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct msm_gpu *gpu = platform_get_drvdata(pdev); + + return gpu->funcs->pm_suspend(gpu); +} +#endif + +static const struct dev_pm_ops adreno_pm_ops = { + SET_RUNTIME_PM_OPS(adreno_suspend, adreno_resume, NULL) +}; + static struct platform_driver adreno_driver = { .probe = adreno_probe, .remove = adreno_remove, .driver = { .name = "adreno", .of_match_table = dt_match, + .pm = &adreno_pm_ops, }, }; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 04e0056f2a49..f6b5040e2079 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -136,6 +136,11 @@ void adreno_recover(struct msm_gpu *gpu) struct msm_ringbuffer *ring; int ret, i; + /* + * XXX pm-runtime?? we *need* the device to be off after this + * so maybe continuing to call ->pm_suspend/resume() is better? + */ + gpu->funcs->pm_suspend(gpu); /* reset ringbuffer(s): */ @@ -155,13 +160,11 @@ void adreno_recover(struct msm_gpu *gpu) gpu->funcs->pm_resume(gpu); - disable_irq(gpu->irq); - ret = gpu->funcs->hw_init(gpu); + ret = msm_gpu_hw_init(gpu); if (ret) { dev_err(dev->dev, "gpu hw init failed: %d\n", ret); /* hmm, oh well? */ } - enable_irq(gpu->irq); } void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) @@ -520,6 +523,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, if (ret) return ret; + pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_enable(&pdev->dev); + ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); if (ret) { dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", @@ -535,12 +542,18 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, return ret; } -void adreno_gpu_cleanup(struct adreno_gpu *gpu) +void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) { - release_firmware(gpu->pm4); - release_firmware(gpu->pfp); + struct msm_gpu *gpu = &adreno_gpu->base; + struct drm_device *dev = gpu->dev; + struct msm_drm_private *priv = dev->dev_private; + struct platform_device *pdev = priv->gpu_pdev; + + release_firmware(adreno_gpu->pm4); + release_firmware(adreno_gpu->pfp); - msm_gpu_cleanup(&gpu->base); + pm_runtime_disable(&pdev->dev); + msm_gpu_cleanup(gpu); } static void adreno_snapshot_os(struct msm_gpu *gpu, diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 969af4c6f0c0..83b34a071ced 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -280,6 +280,10 @@ static int msm_unload(struct drm_device *dev) if (gpu) { mutex_lock(&dev->struct_mutex); + /* + * XXX what do we do here? + * pm_runtime_enable(&pdev->dev); + */ gpu->funcs->pm_suspend(gpu); mutex_unlock(&dev->struct_mutex); gpu->funcs->destroy(gpu); @@ -906,7 +910,9 @@ static int msm_gpu_show(struct drm_device *dev, struct seq_file *m) if (gpu) { seq_printf(m, "%s Status:\n", gpu->name); + pm_runtime_get_sync(&gpu->pdev->dev); gpu->funcs->show(gpu, m); + pm_runtime_put_sync(&gpu->pdev->dev); } return 0; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 7c109fdab545..9b5f9de1a517 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -154,22 +154,9 @@ static int disable_axi(struct msm_gpu *gpu) int msm_gpu_pm_resume(struct msm_gpu *gpu) { - struct drm_device *dev = gpu->dev; - struct msm_drm_private *priv = dev->dev_private; - struct platform_device *pdev = priv->gpu_pdev; int ret; - DBG("%s: active_cnt=%d", gpu->name, gpu->active_cnt); - - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - - if (gpu->active_cnt++ > 0) - return 0; - - if (WARN_ON(gpu->active_cnt <= 0)) - return -EINVAL; - - WARN_ON(pm_runtime_get_sync(&pdev->dev) < 0); + DBG("%s", gpu->name); ret = enable_pwrrail(gpu); if (ret) @@ -186,25 +173,16 @@ int msm_gpu_pm_resume(struct msm_gpu *gpu) if (gpu->aspace && gpu->aspace->mmu) msm_mmu_enable(gpu->aspace->mmu); + gpu->needs_hw_init = true; + return 0; } int msm_gpu_pm_suspend(struct msm_gpu *gpu) { - struct drm_device *dev = gpu->dev; - struct msm_drm_private *priv = dev->dev_private; - struct platform_device *pdev = priv->gpu_pdev; int ret; - DBG("%s: active_cnt=%d", gpu->name, gpu->active_cnt); - - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - - if (--gpu->active_cnt > 0) - return 0; - - if (WARN_ON(gpu->active_cnt < 0)) - return -EINVAL; + DBG("%s", gpu->name); if (gpu->aspace && gpu->aspace->mmu) msm_mmu_disable(gpu->aspace->mmu); @@ -221,57 +199,23 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu) if (ret) return ret; - pm_runtime_put(&pdev->dev); return 0; } -/* - * Inactivity detection (for suspend): - */ - -static void inactive_worker(struct work_struct *work) +int msm_gpu_hw_init(struct msm_gpu *gpu) { - struct msm_gpu *gpu = container_of(work, struct msm_gpu, inactive_work); - struct drm_device *dev = gpu->dev; - - if (gpu->inactive) - return; - - DBG("%s: inactive!\n", gpu->name); - mutex_lock(&dev->struct_mutex); - if (!(msm_gpu_active(gpu) || gpu->inactive)) { - disable_axi(gpu); - disable_clk(gpu); - gpu->inactive = true; - } - mutex_unlock(&dev->struct_mutex); -} - -static void inactive_handler(unsigned long data) -{ - struct msm_gpu *gpu = (struct msm_gpu *)data; - struct msm_drm_private *priv = gpu->dev->dev_private; + int ret; - queue_work(priv->wq, &gpu->inactive_work); -} + if (!gpu->needs_hw_init) + return 0; -/* cancel inactive timer and make sure we are awake: */ -static void inactive_cancel(struct msm_gpu *gpu) -{ - DBG("%s", gpu->name); - del_timer(&gpu->inactive_timer); - if (gpu->inactive) { - enable_clk(gpu); - enable_axi(gpu); - gpu->inactive = false; - } -} + disable_irq(gpu->irq); + ret = gpu->funcs->hw_init(gpu); + if (!ret) + gpu->needs_hw_init = false; + enable_irq(gpu->irq); -static void inactive_start(struct msm_gpu *gpu) -{ - DBG("%s", gpu->name); - mod_timer(&gpu->inactive_timer, - round_jiffies_up(jiffies + DRM_MSM_INACTIVE_JIFFIES)); + return ret; } static void retire_guilty_submit(struct msm_gpu *gpu, @@ -306,8 +250,6 @@ static void recover_worker(struct work_struct *work) struct msm_ringbuffer *ring; int i; - inactive_cancel(gpu); - /* Retire all events that have already passed */ FOR_EACH_RING(gpu, ring, i) retire_submits(gpu, ring, ring->memptrs->fence); @@ -315,7 +257,9 @@ static void recover_worker(struct work_struct *work) retire_guilty_submit(gpu, gpu->funcs->active_ring(gpu)); /* Recover the GPU */ + pm_runtime_get_sync(&gpu->pdev->dev); gpu->funcs->recover(gpu); + pm_runtime_put_sync(&gpu->pdev->dev); /* Replay the remaining on all rings, highest priority first */ for (i = 0; i < gpu->nr_rings; i++) { @@ -438,6 +382,8 @@ void msm_gpu_perfcntr_start(struct msm_gpu *gpu) { unsigned long flags; + pm_runtime_get_sync(&gpu->pdev->dev); + spin_lock_irqsave(&gpu->perf_lock, flags); /* we could dynamically enable/disable perfcntr registers too.. */ gpu->last_sample.active = msm_gpu_active(gpu); @@ -451,6 +397,7 @@ void msm_gpu_perfcntr_start(struct msm_gpu *gpu) void msm_gpu_perfcntr_stop(struct msm_gpu *gpu) { gpu->perfcntr_active = false; + pm_runtime_put_sync(&gpu->pdev->dev); } /* returns -errno or # of cntrs sampled */ @@ -505,6 +452,8 @@ static void retire_submits(struct msm_gpu *gpu, struct msm_ringbuffer *ring, trace_msm_retired(submit, ticks->started, ticks->retired); + pm_runtime_mark_last_busy(&gpu->pdev->dev); + pm_runtime_put_autosuspend(&gpu->pdev->dev); msm_gem_submit_free(submit); } } @@ -550,9 +499,6 @@ static void retire_worker(struct work_struct *work) _retire_ring(gpu, ring, ring->memptrs->fence); mutex_unlock(&dev->struct_mutex); } - - if (!msm_gpu_active(gpu)) - inactive_start(gpu); } /* call from irq handler to schedule work to retire bo's */ @@ -574,7 +520,9 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) submit->fence = FENCE(submit->ring, ++ring->seqno); - inactive_cancel(gpu); + pm_runtime_get_sync(&gpu->pdev->dev); + + msm_gpu_hw_init(gpu); list_add_tail(&submit->node, &ring->submits); @@ -863,23 +811,12 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, gpu->dev = drm; gpu->funcs = funcs; gpu->name = name; - /* - * Set the inactive flag to false, so that when the retire worker - * kicks in from the init path, it knows that it has to turn off the - * clocks. This should be fine to do since this is the init sequence - * and we have an init_lock in msm_open() to protect against bad things - * from happening. - */ - gpu->inactive = false; INIT_LIST_HEAD(&gpu->active_list); INIT_WORK(&gpu->retire_work, retire_worker); - INIT_WORK(&gpu->inactive_work, inactive_worker); INIT_WORK(&gpu->recover_work, recover_worker); - setup_timer(&gpu->inactive_timer, inactive_handler, - (unsigned long)gpu); setup_timer(&gpu->hangcheck_timer, hangcheck_handler, (unsigned long)gpu); @@ -909,8 +846,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, goto fail; } - pm_runtime_enable(&pdev->dev); - ret = get_clocks(pdev, gpu); if (ret) goto fail; @@ -979,6 +914,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, pm_qos_add_request(&gpu->pm_qos_req_dma, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); + gpu->pdev = pdev; + platform_set_drvdata(pdev, gpu); bs_init(gpu); @@ -1000,7 +937,6 @@ fail: msm_gpu_destroy_address_space(gpu->aspace); msm_gpu_destroy_address_space(gpu->secure_aspace); - pm_runtime_disable(&pdev->dev); return ret; } @@ -1031,7 +967,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) } msm_snapshot_destroy(gpu, gpu->snapshot); - pm_runtime_disable(&pdev->dev); msm_gpu_destroy_address_space(gpu->aspace); msm_gpu_destroy_address_space(gpu->secure_aspace); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index eeebfb746f7f..deb12aed5b28 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -83,6 +83,7 @@ struct msm_gpu_funcs { struct msm_gpu { const char *name; struct drm_device *dev; + struct platform_device *pdev; const struct msm_gpu_funcs *funcs; /* performance counters (hw & sw): */ @@ -103,9 +104,8 @@ struct msm_gpu { /* list of GEM active objects: */ struct list_head active_list; - /* is gpu powered/active? */ - int active_cnt; - bool inactive; + /* does gpu need hw_init? */ + bool needs_hw_init; /* worker for handling active-list retiring: */ struct work_struct retire_work; @@ -139,9 +139,7 @@ struct msm_gpu { /* Hang and Inactivity Detection: */ #define DRM_MSM_INACTIVE_PERIOD 66 /* in ms (roughly four frames) */ -#define DRM_MSM_INACTIVE_JIFFIES msecs_to_jiffies(DRM_MSM_INACTIVE_PERIOD) - struct timer_list inactive_timer; - struct work_struct inactive_work; + #define DRM_MSM_HANGCHECK_PERIOD 500 /* in ms */ #define DRM_MSM_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_MSM_HANGCHECK_PERIOD) struct timer_list hangcheck_timer; @@ -255,6 +253,8 @@ static inline void gpu_write64(struct msm_gpu *gpu, u32 lo, u32 hi, u64 val) int msm_gpu_pm_suspend(struct msm_gpu *gpu); int msm_gpu_pm_resume(struct msm_gpu *gpu); +int msm_gpu_hw_init(struct msm_gpu *gpu); + void msm_gpu_perfcntr_start(struct msm_gpu *gpu); void msm_gpu_perfcntr_stop(struct msm_gpu *gpu); int msm_gpu_perfcntr_sample(struct msm_gpu *gpu, uint32_t *activetime, |
