1 /* $NetBSD: intel_guc_ct.c,v 1.4 2021/12/19 12:32:15 riastradh Exp $ */ 2 3 // SPDX-License-Identifier: MIT 4 /* 5 * Copyright 2016-2019 Intel Corporation 6 */ 7 8 #include <sys/cdefs.h> 9 __KERNEL_RCSID(0, "$NetBSD: intel_guc_ct.c,v 1.4 2021/12/19 12:32:15 riastradh Exp $"); 10 11 #include "i915_drv.h" 12 #include "intel_guc_ct.h" 13 14 #ifdef CONFIG_DRM_I915_DEBUG_GUC 15 #define CT_DEBUG_DRIVER(...) DRM_DEBUG_DRIVER(__VA_ARGS__) 16 #else 17 #define CT_DEBUG_DRIVER(...) do { } while (0) 18 #endif 19 20 struct ct_request { 21 struct list_head link; 22 u32 fence; 23 u32 status; 24 u32 response_len; 25 u32 *response_buf; 26 }; 27 28 struct ct_incoming_request { 29 struct list_head link; 30 u32 msg[]; 31 }; 32 33 enum { CTB_SEND = 0, CTB_RECV = 1 }; 34 35 enum { CTB_OWNER_HOST = 0 }; 36 37 static void ct_incoming_request_worker_func(struct work_struct *w); 38 39 /** 40 * intel_guc_ct_init_early - Initialize CT state without requiring device access 41 * @ct: pointer to CT struct 42 */ 43 void intel_guc_ct_init_early(struct intel_guc_ct *ct) 44 { 45 spin_lock_init(&ct->requests.lock); 46 INIT_LIST_HEAD(&ct->requests.pending); 47 INIT_LIST_HEAD(&ct->requests.incoming); 48 INIT_WORK(&ct->requests.worker, ct_incoming_request_worker_func); 49 } 50 51 static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct) 52 { 53 return container_of(ct, struct intel_guc, ct); 54 } 55 56 static inline const char *guc_ct_buffer_type_to_str(u32 type) 57 { 58 switch (type) { 59 case INTEL_GUC_CT_BUFFER_TYPE_SEND: 60 return "SEND"; 61 case INTEL_GUC_CT_BUFFER_TYPE_RECV: 62 return "RECV"; 63 default: 64 return "<invalid>"; 65 } 66 } 67 68 static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc, 69 u32 cmds_addr, u32 size) 70 { 71 CT_DEBUG_DRIVER("CT: init addr=%#x size=%u\n", cmds_addr, size); 72 memset(desc, 0, sizeof(*desc)); 73 desc->addr = cmds_addr; 74 desc->size = size; 75 desc->owner = CTB_OWNER_HOST; 76 } 77 78 static void guc_ct_buffer_desc_reset(struct guc_ct_buffer_desc *desc) 79 { 80 CT_DEBUG_DRIVER("CT: desc %p reset head=%u tail=%u\n", 81 desc, desc->head, desc->tail); 82 desc->head = 0; 83 desc->tail = 0; 84 desc->is_in_error = 0; 85 } 86 87 static int guc_action_register_ct_buffer(struct intel_guc *guc, 88 u32 desc_addr, 89 u32 type) 90 { 91 u32 action[] = { 92 INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER, 93 desc_addr, 94 sizeof(struct guc_ct_buffer_desc), 95 type 96 }; 97 int err; 98 99 /* Can't use generic send(), CT registration must go over MMIO */ 100 err = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0); 101 if (err) 102 DRM_ERROR("CT: register %s buffer failed; err=%d\n", 103 guc_ct_buffer_type_to_str(type), err); 104 return err; 105 } 106 107 static int guc_action_deregister_ct_buffer(struct intel_guc *guc, 108 u32 type) 109 { 110 u32 action[] = { 111 INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER, 112 CTB_OWNER_HOST, 113 type 114 }; 115 int err; 116 117 /* Can't use generic send(), CT deregistration must go over MMIO */ 118 err = intel_guc_send_mmio(guc, action, ARRAY_SIZE(action), NULL, 0); 119 if (err) 120 DRM_ERROR("CT: deregister %s buffer failed; err=%d\n", 121 guc_ct_buffer_type_to_str(type), err); 122 return err; 123 } 124 125 /** 126 * intel_guc_ct_init - Init buffer-based communication 127 * @ct: pointer to CT struct 128 * 129 * Allocate memory required for buffer-based communication. 130 * 131 * Return: 0 on success, a negative errno code on failure. 132 */ 133 int intel_guc_ct_init(struct intel_guc_ct *ct) 134 { 135 struct intel_guc *guc = ct_to_guc(ct); 136 void *blob; 137 int err; 138 int i; 139 140 GEM_BUG_ON(ct->vma); 141 142 /* We allocate 1 page to hold both descriptors and both buffers. 143 * ___________..................... 144 * |desc (SEND)| : 145 * |___________| PAGE/4 146 * :___________....................: 147 * |desc (RECV)| : 148 * |___________| PAGE/4 149 * :_______________________________: 150 * |cmds (SEND) | 151 * | PAGE/4 152 * |_______________________________| 153 * |cmds (RECV) | 154 * | PAGE/4 155 * |_______________________________| 156 * 157 * Each message can use a maximum of 32 dwords and we don't expect to 158 * have more than 1 in flight at any time, so we have enough space. 159 * Some logic further ahead will rely on the fact that there is only 1 160 * page and that it is always mapped, so if the size is changed the 161 * other code will need updating as well. 162 */ 163 164 err = intel_guc_allocate_and_map_vma(guc, PAGE_SIZE, &ct->vma, &blob); 165 if (err) { 166 DRM_ERROR("CT: channel allocation failed; err=%d\n", err); 167 return err; 168 } 169 170 CT_DEBUG_DRIVER("CT: vma base=%#x\n", 171 intel_guc_ggtt_offset(guc, ct->vma)); 172 173 /* store pointers to desc and cmds */ 174 for (i = 0; i < ARRAY_SIZE(ct->ctbs); i++) { 175 GEM_BUG_ON((i != CTB_SEND) && (i != CTB_RECV)); 176 ct->ctbs[i].desc = blob + PAGE_SIZE/4 * i; 177 ct->ctbs[i].cmds = blob + PAGE_SIZE/4 * i + PAGE_SIZE/2; 178 } 179 180 return 0; 181 } 182 183 /** 184 * intel_guc_ct_fini - Fini buffer-based communication 185 * @ct: pointer to CT struct 186 * 187 * Deallocate memory required for buffer-based communication. 188 */ 189 void intel_guc_ct_fini(struct intel_guc_ct *ct) 190 { 191 GEM_BUG_ON(ct->enabled); 192 193 i915_vma_unpin_and_release(&ct->vma, I915_VMA_RELEASE_MAP); 194 spin_lock_destroy(&ct->requests.lock); 195 } 196 197 /** 198 * intel_guc_ct_enable - Enable buffer based command transport. 199 * @ct: pointer to CT struct 200 * 201 * Return: 0 on success, a negative errno code on failure. 202 */ 203 int intel_guc_ct_enable(struct intel_guc_ct *ct) 204 { 205 struct intel_guc *guc = ct_to_guc(ct); 206 u32 base; 207 int err; 208 int i; 209 210 GEM_BUG_ON(ct->enabled); 211 212 /* vma should be already allocated and map'ed */ 213 GEM_BUG_ON(!ct->vma); 214 base = intel_guc_ggtt_offset(guc, ct->vma); 215 216 /* (re)initialize descriptors 217 * cmds buffers are in the second half of the blob page 218 */ 219 for (i = 0; i < ARRAY_SIZE(ct->ctbs); i++) { 220 GEM_BUG_ON((i != CTB_SEND) && (i != CTB_RECV)); 221 guc_ct_buffer_desc_init(ct->ctbs[i].desc, 222 base + PAGE_SIZE/4 * i + PAGE_SIZE/2, 223 PAGE_SIZE/4); 224 } 225 226 /* register buffers, starting wirh RECV buffer 227 * descriptors are in first half of the blob 228 */ 229 err = guc_action_register_ct_buffer(guc, 230 base + PAGE_SIZE/4 * CTB_RECV, 231 INTEL_GUC_CT_BUFFER_TYPE_RECV); 232 if (unlikely(err)) 233 goto err_out; 234 235 err = guc_action_register_ct_buffer(guc, 236 base + PAGE_SIZE/4 * CTB_SEND, 237 INTEL_GUC_CT_BUFFER_TYPE_SEND); 238 if (unlikely(err)) 239 goto err_deregister; 240 241 ct->enabled = true; 242 243 return 0; 244 245 err_deregister: 246 guc_action_deregister_ct_buffer(guc, 247 INTEL_GUC_CT_BUFFER_TYPE_RECV); 248 err_out: 249 DRM_ERROR("CT: can't open channel; err=%d\n", err); 250 return err; 251 } 252 253 /** 254 * intel_guc_ct_disable - Disable buffer based command transport. 255 * @ct: pointer to CT struct 256 */ 257 void intel_guc_ct_disable(struct intel_guc_ct *ct) 258 { 259 struct intel_guc *guc = ct_to_guc(ct); 260 261 GEM_BUG_ON(!ct->enabled); 262 263 ct->enabled = false; 264 265 if (intel_guc_is_running(guc)) { 266 guc_action_deregister_ct_buffer(guc, 267 INTEL_GUC_CT_BUFFER_TYPE_SEND); 268 guc_action_deregister_ct_buffer(guc, 269 INTEL_GUC_CT_BUFFER_TYPE_RECV); 270 } 271 } 272 273 static u32 ct_get_next_fence(struct intel_guc_ct *ct) 274 { 275 /* For now it's trivial */ 276 return ++ct->requests.next_fence; 277 } 278 279 /** 280 * DOC: CTB Host to GuC request 281 * 282 * Format of the CTB Host to GuC request message is as follows:: 283 * 284 * +------------+---------+---------+---------+---------+ 285 * | msg[0] | [1] | [2] | ... | [n-1] | 286 * +------------+---------+---------+---------+---------+ 287 * | MESSAGE | MESSAGE PAYLOAD | 288 * + HEADER +---------+---------+---------+---------+ 289 * | | 0 | 1 | ... | n | 290 * +============+=========+=========+=========+=========+ 291 * | len >= 1 | FENCE | request specific data | 292 * +------+-----+---------+---------+---------+---------+ 293 * 294 * ^-----------------len-------------------^ 295 */ 296 297 static int ctb_write(struct intel_guc_ct_buffer *ctb, 298 const u32 *action, 299 u32 len /* in dwords */, 300 u32 fence, 301 bool want_response) 302 { 303 struct guc_ct_buffer_desc *desc = ctb->desc; 304 u32 head = desc->head / 4; /* in dwords */ 305 u32 tail = desc->tail / 4; /* in dwords */ 306 u32 size = desc->size / 4; /* in dwords */ 307 u32 used; /* in dwords */ 308 u32 header; 309 u32 *cmds = ctb->cmds; 310 unsigned int i; 311 312 GEM_BUG_ON(desc->size % 4); 313 GEM_BUG_ON(desc->head % 4); 314 GEM_BUG_ON(desc->tail % 4); 315 GEM_BUG_ON(tail >= size); 316 317 /* 318 * tail == head condition indicates empty. GuC FW does not support 319 * using up the entire buffer to get tail == head meaning full. 320 */ 321 if (tail < head) 322 used = (size - head) + tail; 323 else 324 used = tail - head; 325 326 /* make sure there is a space including extra dw for the fence */ 327 if (unlikely(used + len + 1 >= size)) 328 return -ENOSPC; 329 330 /* 331 * Write the message. The format is the following: 332 * DW0: header (including action code) 333 * DW1: fence 334 * DW2+: action data 335 */ 336 header = (len << GUC_CT_MSG_LEN_SHIFT) | 337 (GUC_CT_MSG_WRITE_FENCE_TO_DESC) | 338 (want_response ? GUC_CT_MSG_SEND_STATUS : 0) | 339 (action[0] << GUC_CT_MSG_ACTION_SHIFT); 340 341 CT_DEBUG_DRIVER("CT: writing %*ph %*ph %*ph\n", 342 4, &header, 4, &fence, 343 4 * (len - 1), &action[1]); 344 345 cmds[tail] = header; 346 tail = (tail + 1) % size; 347 348 cmds[tail] = fence; 349 tail = (tail + 1) % size; 350 351 for (i = 1; i < len; i++) { 352 cmds[tail] = action[i]; 353 tail = (tail + 1) % size; 354 } 355 356 /* now update desc tail (back in bytes) */ 357 desc->tail = tail * 4; 358 GEM_BUG_ON(desc->tail > desc->size); 359 360 return 0; 361 } 362 363 /** 364 * wait_for_ctb_desc_update - Wait for the CT buffer descriptor update. 365 * @desc: buffer descriptor 366 * @fence: response fence 367 * @status: placeholder for status 368 * 369 * Guc will update CT buffer descriptor with new fence and status 370 * after processing the command identified by the fence. Wait for 371 * specified fence and then read from the descriptor status of the 372 * command. 373 * 374 * Return: 375 * * 0 response received (status is valid) 376 * * -ETIMEDOUT no response within hardcoded timeout 377 * * -EPROTO no response, CT buffer is in error 378 */ 379 static int wait_for_ctb_desc_update(struct guc_ct_buffer_desc *desc, 380 u32 fence, 381 u32 *status) 382 { 383 int err; 384 385 /* 386 * Fast commands should complete in less than 10us, so sample quickly 387 * up to that length of time, then switch to a slower sleep-wait loop. 388 * No GuC command should ever take longer than 10ms. 389 */ 390 #define done (READ_ONCE(desc->fence) == fence) 391 #ifdef __NetBSD__ 392 int timo = 10; 393 err = 0; 394 while (!done) { 395 if (--timo == 0) { 396 kpause("intelguc", false, mstohz(10), NULL); 397 if (!done) 398 err = -ETIMEDOUT; 399 break; 400 } 401 } 402 #else 403 err = wait_for_us(done, 10); 404 if (err) 405 err = wait_for(done, 10); 406 #endif 407 #undef done 408 409 if (unlikely(err)) { 410 DRM_ERROR("CT: fence %u failed; reported fence=%u\n", 411 fence, desc->fence); 412 413 if (WARN_ON(desc->is_in_error)) { 414 /* Something went wrong with the messaging, try to reset 415 * the buffer and hope for the best 416 */ 417 guc_ct_buffer_desc_reset(desc); 418 err = -EPROTO; 419 } 420 } 421 422 *status = desc->status; 423 return err; 424 } 425 426 /** 427 * wait_for_ct_request_update - Wait for CT request state update. 428 * @req: pointer to pending request 429 * @status: placeholder for status 430 * 431 * For each sent request, Guc shall send bac CT response message. 432 * Our message handler will update status of tracked request once 433 * response message with given fence is received. Wait here and 434 * check for valid response status value. 435 * 436 * Return: 437 * * 0 response received (status is valid) 438 * * -ETIMEDOUT no response within hardcoded timeout 439 */ 440 static int wait_for_ct_request_update(struct ct_request *req, u32 *status) 441 { 442 int err; 443 444 /* 445 * Fast commands should complete in less than 10us, so sample quickly 446 * up to that length of time, then switch to a slower sleep-wait loop. 447 * No GuC command should ever take longer than 10ms. 448 */ 449 #define done INTEL_GUC_MSG_IS_RESPONSE(READ_ONCE(req->status)) 450 #ifdef __NetBSD__ 451 int timo = 10; 452 err = 0; 453 while (!done) { 454 if (--timo == 0) { 455 kpause("intelguc", false, mstohz(10), NULL); 456 if (!done) 457 err = -ETIMEDOUT; 458 break; 459 } 460 } 461 #else 462 err = wait_for_us(done, 10); 463 if (err) 464 err = wait_for(done, 10); 465 #endif 466 #undef done 467 468 if (unlikely(err)) 469 DRM_ERROR("CT: fence %u err %d\n", req->fence, err); 470 471 *status = req->status; 472 return err; 473 } 474 475 static int ct_send(struct intel_guc_ct *ct, 476 const u32 *action, 477 u32 len, 478 u32 *response_buf, 479 u32 response_buf_size, 480 u32 *status) 481 { 482 struct intel_guc_ct_buffer *ctb = &ct->ctbs[CTB_SEND]; 483 struct guc_ct_buffer_desc *desc = ctb->desc; 484 struct ct_request request; 485 unsigned long flags; 486 u32 fence; 487 int err; 488 489 GEM_BUG_ON(!ct->enabled); 490 GEM_BUG_ON(!len); 491 GEM_BUG_ON(len & ~GUC_CT_MSG_LEN_MASK); 492 GEM_BUG_ON(!response_buf && response_buf_size); 493 494 fence = ct_get_next_fence(ct); 495 request.fence = fence; 496 request.status = 0; 497 request.response_len = response_buf_size; 498 request.response_buf = response_buf; 499 500 spin_lock_irqsave(&ct->requests.lock, flags); 501 list_add_tail(&request.link, &ct->requests.pending); 502 spin_unlock_irqrestore(&ct->requests.lock, flags); 503 504 err = ctb_write(ctb, action, len, fence, !!response_buf); 505 if (unlikely(err)) 506 goto unlink; 507 508 intel_guc_notify(ct_to_guc(ct)); 509 510 if (response_buf) 511 err = wait_for_ct_request_update(&request, status); 512 else 513 err = wait_for_ctb_desc_update(desc, fence, status); 514 if (unlikely(err)) 515 goto unlink; 516 517 if (!INTEL_GUC_MSG_IS_RESPONSE_SUCCESS(*status)) { 518 err = -EIO; 519 goto unlink; 520 } 521 522 if (response_buf) { 523 /* There shall be no data in the status */ 524 WARN_ON(INTEL_GUC_MSG_TO_DATA(request.status)); 525 /* Return actual response len */ 526 err = request.response_len; 527 } else { 528 /* There shall be no response payload */ 529 WARN_ON(request.response_len); 530 /* Return data decoded from the status dword */ 531 err = INTEL_GUC_MSG_TO_DATA(*status); 532 } 533 534 unlink: 535 spin_lock_irqsave(&ct->requests.lock, flags); 536 list_del(&request.link); 537 spin_unlock_irqrestore(&ct->requests.lock, flags); 538 539 return err; 540 } 541 542 /* 543 * Command Transport (CT) buffer based GuC send function. 544 */ 545 int intel_guc_ct_send(struct intel_guc_ct *ct, const u32 *action, u32 len, 546 u32 *response_buf, u32 response_buf_size) 547 { 548 struct intel_guc *guc = ct_to_guc(ct); 549 u32 status = ~0; /* undefined */ 550 int ret; 551 552 if (unlikely(!ct->enabled)) { 553 WARN(1, "Unexpected send: action=%#x\n", *action); 554 return -ENODEV; 555 } 556 557 mutex_lock(&guc->send_mutex); 558 559 ret = ct_send(ct, action, len, response_buf, response_buf_size, &status); 560 if (unlikely(ret < 0)) { 561 DRM_ERROR("CT: send action %#X failed; err=%d status=%#X\n", 562 action[0], ret, status); 563 } else if (unlikely(ret)) { 564 CT_DEBUG_DRIVER("CT: send action %#x returned %d (%#x)\n", 565 action[0], ret, ret); 566 } 567 568 mutex_unlock(&guc->send_mutex); 569 return ret; 570 } 571 572 static inline unsigned int ct_header_get_len(u32 header) 573 { 574 return (header >> GUC_CT_MSG_LEN_SHIFT) & GUC_CT_MSG_LEN_MASK; 575 } 576 577 static inline unsigned int ct_header_get_action(u32 header) 578 { 579 return (header >> GUC_CT_MSG_ACTION_SHIFT) & GUC_CT_MSG_ACTION_MASK; 580 } 581 582 static inline bool ct_header_is_response(u32 header) 583 { 584 return !!(header & GUC_CT_MSG_IS_RESPONSE); 585 } 586 587 static int ctb_read(struct intel_guc_ct_buffer *ctb, u32 *data) 588 { 589 struct guc_ct_buffer_desc *desc = ctb->desc; 590 u32 head = desc->head / 4; /* in dwords */ 591 u32 tail = desc->tail / 4; /* in dwords */ 592 u32 size = desc->size / 4; /* in dwords */ 593 u32 *cmds = ctb->cmds; 594 s32 available; /* in dwords */ 595 unsigned int len; 596 unsigned int i; 597 598 GEM_BUG_ON(desc->size % 4); 599 GEM_BUG_ON(desc->head % 4); 600 GEM_BUG_ON(desc->tail % 4); 601 GEM_BUG_ON(tail >= size); 602 GEM_BUG_ON(head >= size); 603 604 /* tail == head condition indicates empty */ 605 available = tail - head; 606 if (unlikely(available == 0)) 607 return -ENODATA; 608 609 /* beware of buffer wrap case */ 610 if (unlikely(available < 0)) 611 available += size; 612 CT_DEBUG_DRIVER("CT: available %d (%u:%u)\n", available, head, tail); 613 GEM_BUG_ON(available < 0); 614 615 data[0] = cmds[head]; 616 head = (head + 1) % size; 617 618 /* message len with header */ 619 len = ct_header_get_len(data[0]) + 1; 620 if (unlikely(len > (u32)available)) { 621 DRM_ERROR("CT: incomplete message %*ph %*ph %*ph\n", 622 4, data, 623 4 * (head + available - 1 > size ? 624 size - head : available - 1), &cmds[head], 625 4 * (head + available - 1 > size ? 626 available - 1 - size + head : 0), &cmds[0]); 627 return -EPROTO; 628 } 629 630 for (i = 1; i < len; i++) { 631 data[i] = cmds[head]; 632 head = (head + 1) % size; 633 } 634 CT_DEBUG_DRIVER("CT: received %*ph\n", 4 * len, data); 635 636 desc->head = head * 4; 637 return 0; 638 } 639 640 /** 641 * DOC: CTB GuC to Host response 642 * 643 * Format of the CTB GuC to Host response message is as follows:: 644 * 645 * +------------+---------+---------+---------+---------+---------+ 646 * | msg[0] | [1] | [2] | [3] | ... | [n-1] | 647 * +------------+---------+---------+---------+---------+---------+ 648 * | MESSAGE | MESSAGE PAYLOAD | 649 * + HEADER +---------+---------+---------+---------+---------+ 650 * | | 0 | 1 | 2 | ... | n | 651 * +============+=========+=========+=========+=========+=========+ 652 * | len >= 2 | FENCE | STATUS | response specific data | 653 * +------+-----+---------+---------+---------+---------+---------+ 654 * 655 * ^-----------------------len-----------------------^ 656 */ 657 658 static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg) 659 { 660 u32 header = msg[0]; 661 u32 len = ct_header_get_len(header); 662 u32 msglen = len + 1; /* total message length including header */ 663 u32 fence; 664 u32 status; 665 u32 datalen; 666 struct ct_request *req; 667 bool found = false; 668 669 GEM_BUG_ON(!ct_header_is_response(header)); 670 GEM_BUG_ON(!in_irq()); 671 672 /* Response payload shall at least include fence and status */ 673 if (unlikely(len < 2)) { 674 DRM_ERROR("CT: corrupted response %*ph\n", 4 * msglen, msg); 675 return -EPROTO; 676 } 677 678 fence = msg[1]; 679 status = msg[2]; 680 datalen = len - 2; 681 682 /* Format of the status follows RESPONSE message */ 683 if (unlikely(!INTEL_GUC_MSG_IS_RESPONSE(status))) { 684 DRM_ERROR("CT: corrupted response %*ph\n", 4 * msglen, msg); 685 return -EPROTO; 686 } 687 688 CT_DEBUG_DRIVER("CT: response fence %u status %#x\n", fence, status); 689 690 spin_lock(&ct->requests.lock); 691 list_for_each_entry(req, &ct->requests.pending, link) { 692 if (unlikely(fence != req->fence)) { 693 CT_DEBUG_DRIVER("CT: request %u awaits response\n", 694 req->fence); 695 continue; 696 } 697 if (unlikely(datalen > req->response_len)) { 698 DRM_ERROR("CT: response %u too long %*ph\n", 699 req->fence, 4 * msglen, msg); 700 datalen = 0; 701 } 702 if (datalen) 703 memcpy(req->response_buf, msg + 3, 4 * datalen); 704 req->response_len = datalen; 705 WRITE_ONCE(req->status, status); 706 found = true; 707 break; 708 } 709 spin_unlock(&ct->requests.lock); 710 711 if (!found) 712 DRM_ERROR("CT: unsolicited response %*ph\n", 4 * msglen, msg); 713 return 0; 714 } 715 716 static void ct_process_request(struct intel_guc_ct *ct, 717 u32 action, u32 len, const u32 *payload) 718 { 719 struct intel_guc *guc = ct_to_guc(ct); 720 int ret; 721 722 CT_DEBUG_DRIVER("CT: request %x %*ph\n", action, 4 * len, payload); 723 724 switch (action) { 725 case INTEL_GUC_ACTION_DEFAULT: 726 ret = intel_guc_to_host_process_recv_msg(guc, payload, len); 727 if (unlikely(ret)) 728 goto fail_unexpected; 729 break; 730 731 default: 732 fail_unexpected: 733 DRM_ERROR("CT: unexpected request %x %*ph\n", 734 action, 4 * len, payload); 735 break; 736 } 737 } 738 739 static bool ct_process_incoming_requests(struct intel_guc_ct *ct) 740 { 741 unsigned long flags; 742 struct ct_incoming_request *request; 743 u32 header; 744 u32 *payload; 745 bool done; 746 747 spin_lock_irqsave(&ct->requests.lock, flags); 748 request = list_first_entry_or_null(&ct->requests.incoming, 749 struct ct_incoming_request, link); 750 if (request) 751 list_del(&request->link); 752 done = !!list_empty(&ct->requests.incoming); 753 spin_unlock_irqrestore(&ct->requests.lock, flags); 754 755 if (!request) 756 return true; 757 758 header = request->msg[0]; 759 payload = &request->msg[1]; 760 ct_process_request(ct, 761 ct_header_get_action(header), 762 ct_header_get_len(header), 763 payload); 764 765 kfree(request); 766 return done; 767 } 768 769 static void ct_incoming_request_worker_func(struct work_struct *w) 770 { 771 struct intel_guc_ct *ct = 772 container_of(w, struct intel_guc_ct, requests.worker); 773 bool done; 774 775 done = ct_process_incoming_requests(ct); 776 if (!done) 777 queue_work(system_unbound_wq, &ct->requests.worker); 778 } 779 780 /** 781 * DOC: CTB GuC to Host request 782 * 783 * Format of the CTB GuC to Host request message is as follows:: 784 * 785 * +------------+---------+---------+---------+---------+---------+ 786 * | msg[0] | [1] | [2] | [3] | ... | [n-1] | 787 * +------------+---------+---------+---------+---------+---------+ 788 * | MESSAGE | MESSAGE PAYLOAD | 789 * + HEADER +---------+---------+---------+---------+---------+ 790 * | | 0 | 1 | 2 | ... | n | 791 * +============+=========+=========+=========+=========+=========+ 792 * | len | request specific data | 793 * +------+-----+---------+---------+---------+---------+---------+ 794 * 795 * ^-----------------------len-----------------------^ 796 */ 797 798 static int ct_handle_request(struct intel_guc_ct *ct, const u32 *msg) 799 { 800 u32 header = msg[0]; 801 u32 len = ct_header_get_len(header); 802 u32 msglen = len + 1; /* total message length including header */ 803 struct ct_incoming_request *request; 804 unsigned long flags; 805 806 GEM_BUG_ON(ct_header_is_response(header)); 807 808 request = kmalloc(sizeof(*request) + 4 * msglen, GFP_ATOMIC); 809 if (unlikely(!request)) { 810 DRM_ERROR("CT: dropping request %*ph\n", 4 * msglen, msg); 811 return 0; /* XXX: -ENOMEM ? */ 812 } 813 memcpy(request->msg, msg, 4 * msglen); 814 815 spin_lock_irqsave(&ct->requests.lock, flags); 816 list_add_tail(&request->link, &ct->requests.incoming); 817 spin_unlock_irqrestore(&ct->requests.lock, flags); 818 819 queue_work(system_unbound_wq, &ct->requests.worker); 820 return 0; 821 } 822 823 /* 824 * When we're communicating with the GuC over CT, GuC uses events 825 * to notify us about new messages being posted on the RECV buffer. 826 */ 827 void intel_guc_ct_event_handler(struct intel_guc_ct *ct) 828 { 829 struct intel_guc_ct_buffer *ctb = &ct->ctbs[CTB_RECV]; 830 u32 msg[GUC_CT_MSG_LEN_MASK + 1]; /* one extra dw for the header */ 831 int err = 0; 832 833 if (unlikely(!ct->enabled)) { 834 WARN(1, "Unexpected GuC event received while CT disabled!\n"); 835 return; 836 } 837 838 do { 839 err = ctb_read(ctb, msg); 840 if (err) 841 break; 842 843 if (ct_header_is_response(msg[0])) 844 err = ct_handle_response(ct, msg); 845 else 846 err = ct_handle_request(ct, msg); 847 } while (!err); 848 849 if (GEM_WARN_ON(err == -EPROTO)) { 850 DRM_ERROR("CT: corrupted message detected!\n"); 851 ctb->desc->is_in_error = 1; 852 } 853 } 854 855