1 // SPDX-License-Identifier: MIT 2 #include <linux/debugfs.h> 3 #include <linux/string.h> 4 5 #include <drm/drm_crtc.h> 6 #include <drm/drm_atomic_helper.h> 7 #include <drm/drm_vblank.h> 8 #include <drm/drm_vblank_work.h> 9 10 #include <nvif/class.h> 11 #include <nvif/cl0002.h> 12 #include <nvif/timer.h> 13 14 #include <nvhw/class/cl907d.h> 15 16 #include "nouveau_drv.h" 17 #include "core.h" 18 #include "head.h" 19 #include "wndw.h" 20 #include "handles.h" 21 #include "crc.h" 22 23 static const char * const nv50_crc_sources[] = { 24 [NV50_CRC_SOURCE_NONE] = "none", 25 [NV50_CRC_SOURCE_AUTO] = "auto", 26 [NV50_CRC_SOURCE_RG] = "rg", 27 [NV50_CRC_SOURCE_OUTP_ACTIVE] = "outp-active", 28 [NV50_CRC_SOURCE_OUTP_COMPLETE] = "outp-complete", 29 [NV50_CRC_SOURCE_OUTP_INACTIVE] = "outp-inactive", 30 }; 31 32 static int nv50_crc_parse_source(const char *buf, enum nv50_crc_source *s) 33 { 34 int i; 35 36 if (!buf) { 37 *s = NV50_CRC_SOURCE_NONE; 38 return 0; 39 } 40 41 i = match_string(nv50_crc_sources, ARRAY_SIZE(nv50_crc_sources), buf); 42 if (i < 0) 43 return i; 44 45 *s = i; 46 return 0; 47 } 48 49 int 50 nv50_crc_verify_source(struct drm_crtc *crtc, const char *source_name, 51 size_t *values_cnt) 52 { 53 struct nouveau_drm *drm = nouveau_drm(crtc->dev); 54 enum nv50_crc_source source; 55 56 if (nv50_crc_parse_source(source_name, &source) < 0) { 57 NV_DEBUG(drm, "unknown source %s\n", source_name); 58 return -EINVAL; 59 } 60 61 *values_cnt = 1; 62 return 0; 63 } 64 65 const char *const *nv50_crc_get_sources(struct drm_crtc *crtc, size_t *count) 66 { 67 *count = ARRAY_SIZE(nv50_crc_sources); 68 return nv50_crc_sources; 69 } 70 71 static void 72 nv50_crc_program_ctx(struct nv50_head *head, 73 struct nv50_crc_notifier_ctx *ctx) 74 { 75 struct nv50_disp *disp = nv50_disp(head->base.base.dev); 76 struct nv50_core *core = disp->core; 77 u32 interlock[NV50_DISP_INTERLOCK__SIZE] = { 0 }; 78 79 core->func->crc->set_ctx(head, ctx); 80 core->func->update(core, interlock, false); 81 } 82 83 static void nv50_crc_ctx_flip_work(struct kthread_work *base) 84 { 85 struct drm_vblank_work *work = to_drm_vblank_work(base); 86 struct nv50_crc *crc = container_of(work, struct nv50_crc, flip_work); 87 struct nv50_head *head = container_of(crc, struct nv50_head, crc); 88 struct drm_crtc *crtc = &head->base.base; 89 struct drm_device *dev = crtc->dev; 90 struct nv50_disp *disp = nv50_disp(dev); 91 const uint64_t start_vbl = drm_crtc_vblank_count(crtc); 92 uint64_t end_vbl; 93 u8 new_idx = crc->ctx_idx ^ 1; 94 95 /* 96 * We don't want to accidentally wait for longer then the vblank, so 97 * try again for the next vblank if we don't grab the lock 98 */ 99 if (!mutex_trylock(&disp->mutex)) { 100 drm_dbg_kms(dev, "Lock contended, delaying CRC ctx flip for %s\n", crtc->name); 101 drm_vblank_work_schedule(work, start_vbl + 1, true); 102 return; 103 } 104 105 drm_dbg_kms(dev, "Flipping notifier ctx for %s (%d -> %d)\n", 106 crtc->name, crc->ctx_idx, new_idx); 107 108 nv50_crc_program_ctx(head, NULL); 109 nv50_crc_program_ctx(head, &crc->ctx[new_idx]); 110 mutex_unlock(&disp->mutex); 111 112 end_vbl = drm_crtc_vblank_count(crtc); 113 if (unlikely(end_vbl != start_vbl)) 114 NV_ERROR(nouveau_drm(dev), 115 "Failed to flip CRC context on %s on time (%llu > %llu)\n", 116 crtc->name, end_vbl, start_vbl); 117 118 spin_lock_irq(&crc->lock); 119 crc->ctx_changed = true; 120 spin_unlock_irq(&crc->lock); 121 } 122 123 static inline void nv50_crc_reset_ctx(struct nv50_crc_notifier_ctx *ctx) 124 { 125 memset_io(ctx->mem.object.map.ptr, 0, ctx->mem.object.map.size); 126 } 127 128 static void 129 nv50_crc_get_entries(struct nv50_head *head, 130 const struct nv50_crc_func *func, 131 enum nv50_crc_source source) 132 { 133 struct drm_crtc *crtc = &head->base.base; 134 struct nv50_crc *crc = &head->crc; 135 u32 output_crc; 136 137 while (crc->entry_idx < func->num_entries) { 138 /* 139 * While Nvidia's documentation says CRCs are written on each 140 * subsequent vblank after being enabled, in practice they 141 * aren't written immediately. 142 */ 143 output_crc = func->get_entry(head, &crc->ctx[crc->ctx_idx], 144 source, crc->entry_idx); 145 if (!output_crc) 146 return; 147 148 drm_crtc_add_crc_entry(crtc, true, crc->frame, &output_crc); 149 crc->frame++; 150 crc->entry_idx++; 151 } 152 } 153 154 void nv50_crc_handle_vblank(struct nv50_head *head) 155 { 156 struct drm_crtc *crtc = &head->base.base; 157 struct nv50_crc *crc = &head->crc; 158 const struct nv50_crc_func *func = 159 nv50_disp(head->base.base.dev)->core->func->crc; 160 struct nv50_crc_notifier_ctx *ctx; 161 bool need_reschedule = false; 162 163 if (!func) 164 return; 165 166 /* 167 * We don't lose events if we aren't able to report CRCs until the 168 * next vblank, so only report CRCs if the locks we need aren't 169 * contended to prevent missing an actual vblank event 170 */ 171 if (!spin_trylock(&crc->lock)) 172 return; 173 174 if (!crc->src) 175 goto out; 176 177 ctx = &crc->ctx[crc->ctx_idx]; 178 if (crc->ctx_changed && func->ctx_finished(head, ctx)) { 179 nv50_crc_get_entries(head, func, crc->src); 180 181 crc->ctx_idx ^= 1; 182 crc->entry_idx = 0; 183 crc->ctx_changed = false; 184 185 /* 186 * Unfortunately when notifier contexts are changed during CRC 187 * capture, we will inevitably lose the CRC entry for the 188 * frame where the hardware actually latched onto the first 189 * UPDATE. According to Nvidia's hardware engineers, there's 190 * no workaround for this. 191 * 192 * Now, we could try to be smart here and calculate the number 193 * of missed CRCs based on audit timestamps, but those were 194 * removed starting with volta. Since we always flush our 195 * updates back-to-back without waiting, we'll just be 196 * optimistic and assume we always miss exactly one frame. 197 */ 198 drm_dbg_kms(head->base.base.dev, 199 "Notifier ctx flip for head-%d finished, lost CRC for frame %llu\n", 200 head->base.index, crc->frame); 201 crc->frame++; 202 203 nv50_crc_reset_ctx(ctx); 204 need_reschedule = true; 205 } 206 207 nv50_crc_get_entries(head, func, crc->src); 208 209 if (need_reschedule) 210 drm_vblank_work_schedule(&crc->flip_work, 211 drm_crtc_vblank_count(crtc) 212 + crc->flip_threshold 213 - crc->entry_idx, 214 true); 215 216 out: 217 spin_unlock(&crc->lock); 218 } 219 220 static void nv50_crc_wait_ctx_finished(struct nv50_head *head, 221 const struct nv50_crc_func *func, 222 struct nv50_crc_notifier_ctx *ctx) 223 { 224 struct drm_device *dev = head->base.base.dev; 225 struct nouveau_drm *drm = nouveau_drm(dev); 226 s64 ret; 227 228 ret = nvif_msec(&drm->client.device, 50, 229 if (func->ctx_finished(head, ctx)) break;); 230 if (ret == -ETIMEDOUT) 231 NV_ERROR(drm, 232 "CRC notifier ctx for head %d not finished after 50ms\n", 233 head->base.index); 234 else if (ret) 235 NV_ATOMIC(drm, 236 "CRC notifier ctx for head-%d finished after %lldns\n", 237 head->base.index, ret); 238 } 239 240 void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) 241 { 242 struct drm_crtc_state *crtc_state; 243 struct drm_crtc *crtc; 244 int i; 245 246 for_each_new_crtc_in_state(state, crtc, crtc_state, i) { 247 struct nv50_head *head = nv50_head(crtc); 248 struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); 249 struct nv50_crc *crc = &head->crc; 250 251 if (!asyh->clr.crc) 252 continue; 253 254 spin_lock_irq(&crc->lock); 255 crc->src = NV50_CRC_SOURCE_NONE; 256 spin_unlock_irq(&crc->lock); 257 258 drm_crtc_vblank_put(crtc); 259 drm_vblank_work_cancel_sync(&crc->flip_work); 260 261 NV_ATOMIC(nouveau_drm(crtc->dev), 262 "CRC reporting on vblank for head-%d disabled\n", 263 head->base.index); 264 265 /* CRC generation is still enabled in hw, we'll just report 266 * any remaining CRC entries ourselves after it gets disabled 267 * in hardware 268 */ 269 } 270 } 271 272 void nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) 273 { 274 struct drm_crtc_state *new_crtc_state; 275 struct drm_crtc *crtc; 276 int i; 277 278 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { 279 struct nv50_head *head = nv50_head(crtc); 280 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state); 281 struct nv50_crc *crc = &head->crc; 282 int i; 283 284 if (!asyh->set.crc) 285 continue; 286 287 crc->entry_idx = 0; 288 crc->ctx_changed = false; 289 for (i = 0; i < ARRAY_SIZE(crc->ctx); i++) 290 nv50_crc_reset_ctx(&crc->ctx[i]); 291 } 292 } 293 294 void nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) 295 { 296 const struct nv50_crc_func *func = 297 nv50_disp(state->dev)->core->func->crc; 298 struct drm_crtc_state *new_crtc_state; 299 struct drm_crtc *crtc; 300 int i; 301 302 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { 303 struct nv50_head *head = nv50_head(crtc); 304 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state); 305 struct nv50_crc *crc = &head->crc; 306 struct nv50_crc_notifier_ctx *ctx = &crc->ctx[crc->ctx_idx]; 307 308 if (!asyh->clr.crc) 309 continue; 310 311 if (crc->ctx_changed) { 312 nv50_crc_wait_ctx_finished(head, func, ctx); 313 ctx = &crc->ctx[crc->ctx_idx ^ 1]; 314 } 315 nv50_crc_wait_ctx_finished(head, func, ctx); 316 } 317 } 318 319 void nv50_crc_atomic_start_reporting(struct drm_atomic_state *state) 320 { 321 struct drm_crtc_state *crtc_state; 322 struct drm_crtc *crtc; 323 int i; 324 325 for_each_new_crtc_in_state(state, crtc, crtc_state, i) { 326 struct nv50_head *head = nv50_head(crtc); 327 struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); 328 struct nv50_crc *crc = &head->crc; 329 u64 vbl_count; 330 331 if (!asyh->set.crc) 332 continue; 333 334 drm_crtc_vblank_get(crtc); 335 336 spin_lock_irq(&crc->lock); 337 vbl_count = drm_crtc_vblank_count(crtc); 338 crc->frame = vbl_count; 339 crc->src = asyh->crc.src; 340 drm_vblank_work_schedule(&crc->flip_work, 341 vbl_count + crc->flip_threshold, 342 true); 343 spin_unlock_irq(&crc->lock); 344 345 NV_ATOMIC(nouveau_drm(crtc->dev), 346 "CRC reporting on vblank for head-%d enabled\n", 347 head->base.index); 348 } 349 } 350 351 int nv50_crc_atomic_check_head(struct nv50_head *head, 352 struct nv50_head_atom *asyh, 353 struct nv50_head_atom *armh) 354 { 355 struct nv50_atom *atom = nv50_atom(asyh->state.state); 356 bool changed = armh->crc.src != asyh->crc.src; 357 358 if (!armh->crc.src && !asyh->crc.src) { 359 asyh->set.crc = false; 360 asyh->clr.crc = false; 361 return 0; 362 } 363 364 if (drm_atomic_crtc_needs_modeset(&asyh->state) || changed) { 365 asyh->clr.crc = armh->crc.src && armh->state.active; 366 asyh->set.crc = asyh->crc.src && asyh->state.active; 367 if (changed) 368 asyh->set.or |= armh->or.crc_raster != 369 asyh->or.crc_raster; 370 371 if (asyh->clr.crc && asyh->set.crc) 372 atom->flush_disable = true; 373 } else { 374 asyh->set.crc = false; 375 asyh->clr.crc = false; 376 } 377 378 return 0; 379 } 380 381 void nv50_crc_atomic_check_outp(struct nv50_atom *atom) 382 { 383 struct drm_crtc *crtc; 384 struct drm_crtc_state *old_crtc_state, *new_crtc_state; 385 int i; 386 387 if (atom->flush_disable) 388 return; 389 390 for_each_oldnew_crtc_in_state(&atom->state, crtc, old_crtc_state, 391 new_crtc_state, i) { 392 struct nv50_head_atom *armh = nv50_head_atom(old_crtc_state); 393 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state); 394 struct nv50_outp_atom *outp_atom; 395 struct nouveau_encoder *outp; 396 struct drm_encoder *encoder, *enc; 397 398 enc = nv50_head_atom_get_encoder(armh); 399 if (!enc) 400 continue; 401 402 outp = nv50_real_outp(enc); 403 if (!outp) 404 continue; 405 406 encoder = &outp->base.base; 407 408 if (!asyh->clr.crc) 409 continue; 410 411 /* 412 * Re-programming ORs can't be done in the same flush as 413 * disabling CRCs 414 */ 415 list_for_each_entry(outp_atom, &atom->outp, head) { 416 if (outp_atom->encoder == encoder) { 417 if (outp_atom->set.mask) { 418 atom->flush_disable = true; 419 return; 420 } else { 421 break; 422 } 423 } 424 } 425 } 426 } 427 428 static enum nv50_crc_source_type 429 nv50_crc_source_type(struct nouveau_encoder *outp, 430 enum nv50_crc_source source) 431 { 432 struct dcb_output *dcbe = outp->dcb; 433 434 switch (source) { 435 case NV50_CRC_SOURCE_NONE: return NV50_CRC_SOURCE_TYPE_NONE; 436 case NV50_CRC_SOURCE_RG: return NV50_CRC_SOURCE_TYPE_RG; 437 default: break; 438 } 439 440 if (dcbe->location != DCB_LOC_ON_CHIP) 441 return NV50_CRC_SOURCE_TYPE_PIOR; 442 443 switch (dcbe->type) { 444 case DCB_OUTPUT_DP: return NV50_CRC_SOURCE_TYPE_SF; 445 case DCB_OUTPUT_ANALOG: return NV50_CRC_SOURCE_TYPE_DAC; 446 default: return NV50_CRC_SOURCE_TYPE_SOR; 447 } 448 } 449 450 void nv50_crc_atomic_set(struct nv50_head *head, 451 struct nv50_head_atom *asyh) 452 { 453 struct drm_crtc *crtc = &head->base.base; 454 struct drm_device *dev = crtc->dev; 455 struct nv50_crc *crc = &head->crc; 456 const struct nv50_crc_func *func = nv50_disp(dev)->core->func->crc; 457 struct nouveau_encoder *outp; 458 struct drm_encoder *encoder; 459 460 encoder = nv50_head_atom_get_encoder(asyh); 461 if (!encoder) 462 return; 463 464 outp = nv50_real_outp(encoder); 465 if (!outp) 466 return; 467 468 func->set_src(head, outp->outp.or.id, nv50_crc_source_type(outp, asyh->crc.src), 469 &crc->ctx[crc->ctx_idx]); 470 } 471 472 void nv50_crc_atomic_clr(struct nv50_head *head) 473 { 474 const struct nv50_crc_func *func = 475 nv50_disp(head->base.base.dev)->core->func->crc; 476 477 func->set_src(head, 0, NV50_CRC_SOURCE_TYPE_NONE, NULL); 478 } 479 480 static inline int 481 nv50_crc_raster_type(enum nv50_crc_source source) 482 { 483 switch (source) { 484 case NV50_CRC_SOURCE_NONE: 485 case NV50_CRC_SOURCE_AUTO: 486 case NV50_CRC_SOURCE_RG: 487 case NV50_CRC_SOURCE_OUTP_ACTIVE: 488 return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_ACTIVE_RASTER; 489 case NV50_CRC_SOURCE_OUTP_COMPLETE: 490 return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_COMPLETE_RASTER; 491 case NV50_CRC_SOURCE_OUTP_INACTIVE: 492 return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_NON_ACTIVE_RASTER; 493 } 494 495 return 0; 496 } 497 498 /* We handle mapping the memory for CRC notifiers ourselves, since each 499 * notifier needs it's own handle 500 */ 501 static inline int 502 nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu, 503 struct nv50_crc_notifier_ctx *ctx, size_t len, int idx) 504 { 505 struct nv50_core *core = nv50_disp(head->base.base.dev)->core; 506 int ret; 507 508 ret = nvif_mem_ctor_map(mmu, "kmsCrcNtfy", NVIF_MEM_VRAM, len, &ctx->mem); 509 if (ret) 510 return ret; 511 512 ret = nvif_object_ctor(&core->chan.base.user, "kmsCrcNtfyCtxDma", 513 NV50_DISP_HANDLE_CRC_CTX(head, idx), 514 NV_DMA_IN_MEMORY, 515 &(struct nv_dma_v0) { 516 .target = NV_DMA_V0_TARGET_VRAM, 517 .access = NV_DMA_V0_ACCESS_RDWR, 518 .start = ctx->mem.addr, 519 .limit = ctx->mem.addr 520 + ctx->mem.size - 1, 521 }, sizeof(struct nv_dma_v0), 522 &ctx->ntfy); 523 if (ret) 524 goto fail_fini; 525 526 return 0; 527 528 fail_fini: 529 nvif_mem_dtor(&ctx->mem); 530 return ret; 531 } 532 533 static inline void 534 nv50_crc_ctx_fini(struct nv50_crc_notifier_ctx *ctx) 535 { 536 nvif_object_dtor(&ctx->ntfy); 537 nvif_mem_dtor(&ctx->mem); 538 } 539 540 int nv50_crc_set_source(struct drm_crtc *crtc, const char *source_str) 541 { 542 struct drm_device *dev = crtc->dev; 543 struct drm_atomic_state *state; 544 struct drm_modeset_acquire_ctx ctx; 545 struct nv50_head *head = nv50_head(crtc); 546 struct nv50_crc *crc = &head->crc; 547 const struct nv50_crc_func *func = nv50_disp(dev)->core->func->crc; 548 struct nvif_mmu *mmu = &nouveau_drm(dev)->client.mmu; 549 struct nv50_head_atom *asyh; 550 struct drm_crtc_state *crtc_state; 551 enum nv50_crc_source source; 552 int ret = 0, ctx_flags = 0, i; 553 554 ret = nv50_crc_parse_source(source_str, &source); 555 if (ret) 556 return ret; 557 558 /* 559 * Since we don't want the user to accidentally interrupt us as we're 560 * disabling CRCs 561 */ 562 if (source) 563 ctx_flags |= DRM_MODESET_ACQUIRE_INTERRUPTIBLE; 564 drm_modeset_acquire_init(&ctx, ctx_flags); 565 566 state = drm_atomic_state_alloc(dev); 567 if (!state) { 568 ret = -ENOMEM; 569 goto out_acquire_fini; 570 } 571 state->acquire_ctx = &ctx; 572 573 if (source) { 574 for (i = 0; i < ARRAY_SIZE(head->crc.ctx); i++) { 575 ret = nv50_crc_ctx_init(head, mmu, &crc->ctx[i], 576 func->notifier_len, i); 577 if (ret) 578 goto out_ctx_fini; 579 } 580 } 581 582 retry: 583 crtc_state = drm_atomic_get_crtc_state(state, &head->base.base); 584 if (IS_ERR(crtc_state)) { 585 ret = PTR_ERR(crtc_state); 586 if (ret == -EDEADLK) 587 goto deadlock; 588 else if (ret) 589 goto out_drop_locks; 590 } 591 asyh = nv50_head_atom(crtc_state); 592 asyh->crc.src = source; 593 asyh->or.crc_raster = nv50_crc_raster_type(source); 594 595 ret = drm_atomic_commit(state); 596 if (ret == -EDEADLK) 597 goto deadlock; 598 else if (ret) 599 goto out_drop_locks; 600 601 if (!source) { 602 /* 603 * If the user specified a custom flip threshold through 604 * debugfs, reset it 605 */ 606 crc->flip_threshold = func->flip_threshold; 607 } 608 609 out_drop_locks: 610 drm_modeset_drop_locks(&ctx); 611 out_ctx_fini: 612 if (!source || ret) { 613 for (i = 0; i < ARRAY_SIZE(crc->ctx); i++) 614 nv50_crc_ctx_fini(&crc->ctx[i]); 615 } 616 drm_atomic_state_put(state); 617 out_acquire_fini: 618 drm_modeset_acquire_fini(&ctx); 619 return ret; 620 621 deadlock: 622 drm_atomic_state_clear(state); 623 drm_modeset_backoff(&ctx); 624 goto retry; 625 } 626 627 static int 628 nv50_crc_debugfs_flip_threshold_get(struct seq_file *m, void *data) 629 { 630 struct nv50_head *head = m->private; 631 struct drm_crtc *crtc = &head->base.base; 632 struct nv50_crc *crc = &head->crc; 633 int ret; 634 635 ret = drm_modeset_lock_single_interruptible(&crtc->mutex); 636 if (ret) 637 return ret; 638 639 seq_printf(m, "%d\n", crc->flip_threshold); 640 641 drm_modeset_unlock(&crtc->mutex); 642 return ret; 643 } 644 645 static int 646 nv50_crc_debugfs_flip_threshold_open(struct inode *inode, struct file *file) 647 { 648 return single_open(file, nv50_crc_debugfs_flip_threshold_get, 649 inode->i_private); 650 } 651 652 static ssize_t 653 nv50_crc_debugfs_flip_threshold_set(struct file *file, 654 const char __user *ubuf, size_t len, 655 loff_t *offp) 656 { 657 struct seq_file *m = file->private_data; 658 struct nv50_head *head = m->private; 659 struct nv50_head_atom *armh; 660 struct drm_crtc *crtc = &head->base.base; 661 struct nouveau_drm *drm = nouveau_drm(crtc->dev); 662 struct nv50_crc *crc = &head->crc; 663 const struct nv50_crc_func *func = 664 nv50_disp(crtc->dev)->core->func->crc; 665 int value, ret; 666 667 ret = kstrtoint_from_user(ubuf, len, 10, &value); 668 if (ret) 669 return ret; 670 671 if (value > func->flip_threshold) 672 return -EINVAL; 673 else if (value == -1) 674 value = func->flip_threshold; 675 else if (value < -1) 676 return -EINVAL; 677 678 ret = drm_modeset_lock_single_interruptible(&crtc->mutex); 679 if (ret) 680 return ret; 681 682 armh = nv50_head_atom(crtc->state); 683 if (armh->crc.src) { 684 ret = -EBUSY; 685 goto out; 686 } 687 688 NV_DEBUG(drm, 689 "Changing CRC flip threshold for next capture on head-%d to %d\n", 690 head->base.index, value); 691 crc->flip_threshold = value; 692 ret = len; 693 694 out: 695 drm_modeset_unlock(&crtc->mutex); 696 return ret; 697 } 698 699 static const struct file_operations nv50_crc_flip_threshold_fops = { 700 .owner = THIS_MODULE, 701 .open = nv50_crc_debugfs_flip_threshold_open, 702 .read = seq_read, 703 .write = nv50_crc_debugfs_flip_threshold_set, 704 .release = single_release, 705 }; 706 707 int nv50_head_crc_late_register(struct nv50_head *head) 708 { 709 struct drm_crtc *crtc = &head->base.base; 710 const struct nv50_crc_func *func = 711 nv50_disp(crtc->dev)->core->func->crc; 712 struct dentry *root; 713 714 if (!func || !crtc->debugfs_entry) 715 return 0; 716 717 root = debugfs_create_dir("nv_crc", crtc->debugfs_entry); 718 debugfs_create_file("flip_threshold", 0644, root, head, 719 &nv50_crc_flip_threshold_fops); 720 721 return 0; 722 } 723 724 static inline void 725 nv50_crc_init_head(struct nv50_disp *disp, const struct nv50_crc_func *func, 726 struct nv50_head *head) 727 { 728 struct nv50_crc *crc = &head->crc; 729 730 crc->flip_threshold = func->flip_threshold; 731 spin_lock_init(&crc->lock); 732 drm_vblank_work_init(&crc->flip_work, &head->base.base, 733 nv50_crc_ctx_flip_work); 734 } 735 736 void nv50_crc_init(struct drm_device *dev) 737 { 738 struct nv50_disp *disp = nv50_disp(dev); 739 struct drm_crtc *crtc; 740 const struct nv50_crc_func *func = disp->core->func->crc; 741 742 if (!func) 743 return; 744 745 drm_for_each_crtc(crtc, dev) 746 nv50_crc_init_head(disp, func, nv50_head(crtc)); 747 } 748