summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a.c
diff options
context:
space:
mode:
authorRichard Zhao <rizhao@nvidia.com>2016-06-02 20:17:14 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-06-16 17:06:46 -0400
commit86225cb04eb040a83400d5ad6619b3c2318a53f8 (patch)
tree3c61b7b6831ee2f01c9977d77b3ac9bbaf0f3407 /drivers/gpu/nvgpu/gk20a/gk20a.c
parent03164b0f4abeb06d4b5207531b97f11fe4a860dd (diff)
gpu: nvgpu: add read_ptimer to gops
Move all places that read ptimer to use the callback. It's for add vgpu implementation of read ptimer. Bug 1395833 Change-Id: Ia339f2f08d75ca4969a443fffc9a61cff1d3d2b7 Signed-off-by: Richard Zhao <rizhao@nvidia.com> Reviewed-on: http://git-master/r/1159587 (cherry picked from commit a01f804684f875c9cffc31eb2c1038f2f29ec66f) Reviewed-on: http://git-master/r/1158449 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index d21d0527..db77d40f 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -2227,18 +2227,45 @@ gk20a_request_firmware(struct gk20a *g, const char *fw_name)
2227 return fw; 2227 return fw;
2228} 2228}
2229 2229
2230 2230int gk20a_read_ptimer(struct gk20a *g, u64 *value)
2231u64 gk20a_read_ptimer(struct gk20a *g)
2232{ 2231{
2233 u32 time_hi0 = gk20a_readl(g, timer_time_1_r()); 2232 const unsigned int max_iterations = 3;
2234 u32 time_lo = gk20a_readl(g, timer_time_0_r()); 2233 unsigned int i = 0;
2235 u32 time_hi1 = gk20a_readl(g, timer_time_1_r()); 2234 u32 gpu_timestamp_hi_prev = 0;
2236 u32 time_hi = (time_lo & (1L << 31)) ? time_hi0 : time_hi1;
2237 u64 time = ((u64)time_hi << 32) | time_lo;
2238 2235
2239 return time; 2236 if (!value)
2240} 2237 return -EINVAL;
2238
2239 /* Note. The GPU nanosecond timer consists of two 32-bit
2240 * registers (high & low). To detect a possible low register
2241 * wrap-around between the reads, we need to read the high
2242 * register before and after low. The wraparound happens
2243 * approximately once per 4 secs. */
2244
2245 /* get initial gpu_timestamp_hi value */
2246 gpu_timestamp_hi_prev = gk20a_readl(g, timer_time_1_r());
2247
2248 for (i = 0; i < max_iterations; ++i) {
2249 u32 gpu_timestamp_hi = 0;
2250 u32 gpu_timestamp_lo = 0;
2251
2252 gpu_timestamp_lo = gk20a_readl(g, timer_time_0_r());
2253 gpu_timestamp_hi = gk20a_readl(g, timer_time_1_r());
2241 2254
2255 if (gpu_timestamp_hi == gpu_timestamp_hi_prev) {
2256 *value = (((u64)gpu_timestamp_hi) << 32) |
2257 gpu_timestamp_lo;
2258 return 0;
2259 }
2260
2261 /* wrap-around detected, retry */
2262 gpu_timestamp_hi_prev = gpu_timestamp_hi;
2263 }
2264
2265 /* too many iterations, bail out */
2266 gk20a_err(dev_from_gk20a(g), "failed to read ptimer");
2267 return -EBUSY;
2268}
2242 2269
2243MODULE_LICENSE("GPL v2"); 2270MODULE_LICENSE("GPL v2");
2244module_init(gk20a_init); 2271module_init(gk20a_init);