syncpt.c (6df633d0dc333ffce683f46f2856024479b170b9) | syncpt.c (0b8070d12ee2ef62e0b07213d843eb508fba966e) |
---|---|
1/* 2 * Tegra host1x Syncpoints 3 * 4 * Copyright (c) 2010-2013, NVIDIA Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. --- 100 unchanged lines hidden (view full) --- 109 */ 110void host1x_syncpt_restore(struct host1x *host) 111{ 112 struct host1x_syncpt *sp_base = host->syncpt; 113 unsigned int i; 114 115 for (i = 0; i < host1x_syncpt_nb_pts(host); i++) 116 host1x_hw_syncpt_restore(host, sp_base + i); | 1/* 2 * Tegra host1x Syncpoints 3 * 4 * Copyright (c) 2010-2013, NVIDIA Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. --- 100 unchanged lines hidden (view full) --- 109 */ 110void host1x_syncpt_restore(struct host1x *host) 111{ 112 struct host1x_syncpt *sp_base = host->syncpt; 113 unsigned int i; 114 115 for (i = 0; i < host1x_syncpt_nb_pts(host); i++) 116 host1x_hw_syncpt_restore(host, sp_base + i); |
117 |
|
117 for (i = 0; i < host1x_syncpt_nb_bases(host); i++) 118 host1x_hw_syncpt_restore_wait_base(host, sp_base + i); | 118 for (i = 0; i < host1x_syncpt_nb_bases(host); i++) 119 host1x_hw_syncpt_restore_wait_base(host, sp_base + i); |
120 |
|
119 wmb(); 120} 121 122/* 123 * Update the cached syncpoint and waitbase values by reading them 124 * from the registers. 125 */ 126void host1x_syncpt_save(struct host1x *host) --- 49 unchanged lines hidden (view full) --- 176 177/* 178 * Updated sync point form hardware, and returns true if syncpoint is expired, 179 * false if we may need to wait 180 */ 181static bool syncpt_load_min_is_expired(struct host1x_syncpt *sp, u32 thresh) 182{ 183 host1x_hw_syncpt_load(sp->host, sp); | 121 wmb(); 122} 123 124/* 125 * Update the cached syncpoint and waitbase values by reading them 126 * from the registers. 127 */ 128void host1x_syncpt_save(struct host1x *host) --- 49 unchanged lines hidden (view full) --- 178 179/* 180 * Updated sync point form hardware, and returns true if syncpoint is expired, 181 * false if we may need to wait 182 */ 183static bool syncpt_load_min_is_expired(struct host1x_syncpt *sp, u32 thresh) 184{ 185 host1x_hw_syncpt_load(sp->host, sp); |
186 |
|
184 return host1x_syncpt_is_expired(sp, thresh); 185} 186 187/* 188 * Main entrypoint for syncpoint value waits. 189 */ 190int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout, | 187 return host1x_syncpt_is_expired(sp, thresh); 188} 189 190/* 191 * Main entrypoint for syncpoint value waits. 192 */ 193int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout, |
191 u32 *value) | 194 u32 *value) |
192{ 193 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); 194 void *ref; 195 struct host1x_waitlist *waiter; 196 int err = 0, check_count = 0; 197 u32 val; 198 199 if (value) 200 *value = 0; 201 202 /* first check cache */ 203 if (host1x_syncpt_is_expired(sp, thresh)) { 204 if (value) 205 *value = host1x_syncpt_load(sp); | 195{ 196 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); 197 void *ref; 198 struct host1x_waitlist *waiter; 199 int err = 0, check_count = 0; 200 u32 val; 201 202 if (value) 203 *value = 0; 204 205 /* first check cache */ 206 if (host1x_syncpt_is_expired(sp, thresh)) { 207 if (value) 208 *value = host1x_syncpt_load(sp); |
209 |
|
206 return 0; 207 } 208 209 /* try to read from register */ 210 val = host1x_hw_syncpt_load(sp->host, sp); 211 if (host1x_syncpt_is_expired(sp, thresh)) { 212 if (value) 213 *value = val; | 210 return 0; 211 } 212 213 /* try to read from register */ 214 val = host1x_hw_syncpt_load(sp->host, sp); 215 if (host1x_syncpt_is_expired(sp, thresh)) { 216 if (value) 217 *value = val; |
218 |
|
214 goto done; 215 } 216 217 if (!timeout) { 218 err = -EAGAIN; 219 goto done; 220 } 221 --- 14 unchanged lines hidden (view full) --- 236 err = -EAGAIN; 237 /* Caller-specified timeout may be impractically low */ 238 if (timeout < 0) 239 timeout = LONG_MAX; 240 241 /* wait for the syncpoint, or timeout, or signal */ 242 while (timeout) { 243 long check = min_t(long, SYNCPT_CHECK_PERIOD, timeout); | 219 goto done; 220 } 221 222 if (!timeout) { 223 err = -EAGAIN; 224 goto done; 225 } 226 --- 14 unchanged lines hidden (view full) --- 241 err = -EAGAIN; 242 /* Caller-specified timeout may be impractically low */ 243 if (timeout < 0) 244 timeout = LONG_MAX; 245 246 /* wait for the syncpoint, or timeout, or signal */ 247 while (timeout) { 248 long check = min_t(long, SYNCPT_CHECK_PERIOD, timeout); |
244 int remain = wait_event_interruptible_timeout(wq, | 249 int remain; 250 251 remain = wait_event_interruptible_timeout(wq, |
245 syncpt_load_min_is_expired(sp, thresh), 246 check); 247 if (remain > 0 || host1x_syncpt_is_expired(sp, thresh)) { 248 if (value) 249 *value = host1x_syncpt_load(sp); | 252 syncpt_load_min_is_expired(sp, thresh), 253 check); 254 if (remain > 0 || host1x_syncpt_is_expired(sp, thresh)) { 255 if (value) 256 *value = host1x_syncpt_load(sp); |
257 |
|
250 err = 0; | 258 err = 0; |
259 |
|
251 break; 252 } | 260 break; 261 } |
262 |
|
253 if (remain < 0) { 254 err = remain; 255 break; 256 } | 263 if (remain < 0) { 264 err = remain; 265 break; 266 } |
267 |
|
257 timeout -= check; | 268 timeout -= check; |
269 |
|
258 if (timeout && check_count <= MAX_STUCK_CHECK_COUNT) { 259 dev_warn(sp->host->dev, 260 "%s: syncpoint id %u (%s) stuck waiting %d, timeout=%ld\n", 261 current->comm, sp->id, sp->name, 262 thresh, timeout); 263 264 host1x_debug_dump_syncpts(sp->host); | 270 if (timeout && check_count <= MAX_STUCK_CHECK_COUNT) { 271 dev_warn(sp->host->dev, 272 "%s: syncpoint id %u (%s) stuck waiting %d, timeout=%ld\n", 273 current->comm, sp->id, sp->name, 274 thresh, timeout); 275 276 host1x_debug_dump_syncpts(sp->host); |
277 |
|
265 if (check_count == MAX_STUCK_CHECK_COUNT) 266 host1x_debug_dump(sp->host); | 278 if (check_count == MAX_STUCK_CHECK_COUNT) 279 host1x_debug_dump(sp->host); |
280 |
|
267 check_count++; 268 } 269 } | 281 check_count++; 282 } 283 } |
284 |
|
270 host1x_intr_put_ref(sp->host, sp->id, ref); 271 272done: 273 return err; 274} 275EXPORT_SYMBOL(host1x_syncpt_wait); 276 277/* 278 * Returns true if syncpoint is expired, false if we may need to wait 279 */ 280bool host1x_syncpt_is_expired(struct host1x_syncpt *sp, u32 thresh) 281{ 282 u32 current_val; 283 u32 future_val; 284 285 smp_rmb(); | 285 host1x_intr_put_ref(sp->host, sp->id, ref); 286 287done: 288 return err; 289} 290EXPORT_SYMBOL(host1x_syncpt_wait); 291 292/* 293 * Returns true if syncpoint is expired, false if we may need to wait 294 */ 295bool host1x_syncpt_is_expired(struct host1x_syncpt *sp, u32 thresh) 296{ 297 u32 current_val; 298 u32 future_val; 299 300 smp_rmb(); |
301 |
|
286 current_val = (u32)atomic_read(&sp->min_val); 287 future_val = (u32)atomic_read(&sp->max_val); 288 289 /* Note the use of unsigned arithmetic here (mod 1<<32). 290 * 291 * c = current_val = min_val = the current value of the syncpoint. 292 * t = thresh = the value we are checking 293 * f = future_val = max_val = the value c will reach when all --- 82 unchanged lines hidden (view full) --- 376 377 return 0; 378} 379 380struct host1x_syncpt *host1x_syncpt_request(struct device *dev, 381 unsigned long flags) 382{ 383 struct host1x *host = dev_get_drvdata(dev->parent); | 302 current_val = (u32)atomic_read(&sp->min_val); 303 future_val = (u32)atomic_read(&sp->max_val); 304 305 /* Note the use of unsigned arithmetic here (mod 1<<32). 306 * 307 * c = current_val = min_val = the current value of the syncpoint. 308 * t = thresh = the value we are checking 309 * f = future_val = max_val = the value c will reach when all --- 82 unchanged lines hidden (view full) --- 392 393 return 0; 394} 395 396struct host1x_syncpt *host1x_syncpt_request(struct device *dev, 397 unsigned long flags) 398{ 399 struct host1x *host = dev_get_drvdata(dev->parent); |
400 |
|
384 return host1x_syncpt_alloc(host, dev, flags); 385} 386EXPORT_SYMBOL(host1x_syncpt_request); 387 388void host1x_syncpt_free(struct host1x_syncpt *sp) 389{ 390 if (!sp) 391 return; --- 18 unchanged lines hidden (view full) --- 410 411/* 412 * Read max. It indicates how many operations there are in queue, either in 413 * channel or in a software thread. 414 */ 415u32 host1x_syncpt_read_max(struct host1x_syncpt *sp) 416{ 417 smp_rmb(); | 401 return host1x_syncpt_alloc(host, dev, flags); 402} 403EXPORT_SYMBOL(host1x_syncpt_request); 404 405void host1x_syncpt_free(struct host1x_syncpt *sp) 406{ 407 if (!sp) 408 return; --- 18 unchanged lines hidden (view full) --- 427 428/* 429 * Read max. It indicates how many operations there are in queue, either in 430 * channel or in a software thread. 431 */ 432u32 host1x_syncpt_read_max(struct host1x_syncpt *sp) 433{ 434 smp_rmb(); |
435 |
|
418 return (u32)atomic_read(&sp->max_val); 419} 420EXPORT_SYMBOL(host1x_syncpt_read_max); 421 422/* 423 * Read min, which is a shadow of the current sync point value in hardware. 424 */ 425u32 host1x_syncpt_read_min(struct host1x_syncpt *sp) 426{ 427 smp_rmb(); | 436 return (u32)atomic_read(&sp->max_val); 437} 438EXPORT_SYMBOL(host1x_syncpt_read_max); 439 440/* 441 * Read min, which is a shadow of the current sync point value in hardware. 442 */ 443u32 host1x_syncpt_read_min(struct host1x_syncpt *sp) 444{ 445 smp_rmb(); |
446 |
|
428 return (u32)atomic_read(&sp->min_val); 429} 430EXPORT_SYMBOL(host1x_syncpt_read_min); 431 432u32 host1x_syncpt_read(struct host1x_syncpt *sp) 433{ 434 return host1x_syncpt_load(sp); 435} --- 13 unchanged lines hidden (view full) --- 449{ 450 return host->info->nb_mlocks; 451} 452 453struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, unsigned int id) 454{ 455 if (host->info->nb_pts < id) 456 return NULL; | 447 return (u32)atomic_read(&sp->min_val); 448} 449EXPORT_SYMBOL(host1x_syncpt_read_min); 450 451u32 host1x_syncpt_read(struct host1x_syncpt *sp) 452{ 453 return host1x_syncpt_load(sp); 454} --- 13 unchanged lines hidden (view full) --- 468{ 469 return host->info->nb_mlocks; 470} 471 472struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, unsigned int id) 473{ 474 if (host->info->nb_pts < id) 475 return NULL; |
476 |
|
457 return host->syncpt + id; 458} 459EXPORT_SYMBOL(host1x_syncpt_get); 460 461struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp) 462{ 463 return sp ? sp->base : NULL; 464} 465EXPORT_SYMBOL(host1x_syncpt_get_base); 466 467u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base) 468{ 469 return base->id; 470} 471EXPORT_SYMBOL(host1x_syncpt_base_id); | 477 return host->syncpt + id; 478} 479EXPORT_SYMBOL(host1x_syncpt_get); 480 481struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp) 482{ 483 return sp ? sp->base : NULL; 484} 485EXPORT_SYMBOL(host1x_syncpt_get_base); 486 487u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base) 488{ 489 return base->id; 490} 491EXPORT_SYMBOL(host1x_syncpt_base_id); |