root/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. intel_guc_ct_init_early
  2. ct_to_guc
  3. guc_ct_buffer_type_to_str
  4. guc_ct_buffer_desc_init
  5. guc_ct_buffer_desc_reset
  6. guc_action_register_ct_buffer
  7. guc_action_deregister_ct_buffer
  8. ctch_init
  9. ctch_fini
  10. ctch_enable
  11. ctch_disable
  12. ctch_get_next_fence
  13. ctb_write
  14. wait_for_ctb_desc_update
  15. wait_for_ct_request_update
  16. ctch_send
  17. intel_guc_send_ct
  18. ct_header_get_len
  19. ct_header_get_action
  20. ct_header_is_response
  21. ctb_read
  22. ct_handle_response
  23. ct_process_request
  24. ct_process_incoming_requests
  25. ct_incoming_request_worker_func
  26. ct_handle_request
  27. ct_process_host_channel
  28. intel_guc_to_host_event_handler_ct
  29. intel_guc_ct_init
  30. intel_guc_ct_fini
  31. intel_guc_ct_enable
  32. intel_guc_ct_disable

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

/* [<][>][^][v][top][bottom][index][help] */