root/drivers/media/platform/qcom/venus/hfi_msgs.c

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

DEFINITIONS

This source file includes following definitions.
  1. event_seq_changed
  2. event_release_buffer_ref
  3. event_sys_error
  4. event_session_error
  5. hfi_event_notify
  6. hfi_sys_init_done
  7. sys_get_prop_image_version
  8. hfi_sys_property_info
  9. hfi_sys_rel_resource_done
  10. hfi_sys_ping_done
  11. hfi_sys_idle_done
  12. hfi_sys_pc_prepare_done
  13. session_get_prop_profile_level
  14. session_get_prop_buf_req
  15. hfi_session_prop_info
  16. hfi_session_init_done
  17. hfi_session_load_res_done
  18. hfi_session_flush_done
  19. hfi_session_etb_done
  20. hfi_session_ftb_done
  21. hfi_session_start_done
  22. hfi_session_stop_done
  23. hfi_session_rel_res_done
  24. hfi_session_rel_buf_done
  25. hfi_session_end_done
  26. hfi_session_abort_done
  27. hfi_session_get_seq_hdr_done
  28. hfi_process_watchdog_timeout
  29. to_instance
  30. hfi_process_msg_packet

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
   4  * Copyright (C) 2017 Linaro Ltd.
   5  */
   6 #include <linux/hash.h>
   7 #include <linux/list.h>
   8 #include <linux/slab.h>
   9 #include <media/videobuf2-v4l2.h>
  10 
  11 #include "core.h"
  12 #include "hfi.h"
  13 #include "hfi_helper.h"
  14 #include "hfi_msgs.h"
  15 #include "hfi_parser.h"
  16 
  17 static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
  18                               struct hfi_msg_event_notify_pkt *pkt)
  19 {
  20         enum hfi_version ver = core->res->hfi_version;
  21         struct hfi_event_data event = {0};
  22         int num_properties_changed;
  23         struct hfi_framesize *frame_sz;
  24         struct hfi_profile_level *profile_level;
  25         struct hfi_bit_depth *pixel_depth;
  26         struct hfi_pic_struct *pic_struct;
  27         struct hfi_colour_space *colour_info;
  28         struct hfi_buffer_requirements *bufreq;
  29         struct hfi_extradata_input_crop *crop;
  30         u8 *data_ptr;
  31         u32 ptype;
  32 
  33         inst->error = HFI_ERR_NONE;
  34 
  35         switch (pkt->event_data1) {
  36         case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
  37         case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
  38                 break;
  39         default:
  40                 inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;
  41                 goto done;
  42         }
  43 
  44         event.event_type = pkt->event_data1;
  45 
  46         num_properties_changed = pkt->event_data2;
  47         if (!num_properties_changed) {
  48                 inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
  49                 goto done;
  50         }
  51 
  52         data_ptr = (u8 *)&pkt->ext_event_data[0];
  53         do {
  54                 ptype = *((u32 *)data_ptr);
  55                 switch (ptype) {
  56                 case HFI_PROPERTY_PARAM_FRAME_SIZE:
  57                         data_ptr += sizeof(u32);
  58                         frame_sz = (struct hfi_framesize *)data_ptr;
  59                         event.width = frame_sz->width;
  60                         event.height = frame_sz->height;
  61                         data_ptr += sizeof(*frame_sz);
  62                         break;
  63                 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
  64                         data_ptr += sizeof(u32);
  65                         profile_level = (struct hfi_profile_level *)data_ptr;
  66                         event.profile = profile_level->profile;
  67                         event.level = profile_level->level;
  68                         data_ptr += sizeof(*profile_level);
  69                         break;
  70                 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
  71                         data_ptr += sizeof(u32);
  72                         pixel_depth = (struct hfi_bit_depth *)data_ptr;
  73                         event.bit_depth = pixel_depth->bit_depth;
  74                         data_ptr += sizeof(*pixel_depth);
  75                         break;
  76                 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
  77                         data_ptr += sizeof(u32);
  78                         pic_struct = (struct hfi_pic_struct *)data_ptr;
  79                         event.pic_struct = pic_struct->progressive_only;
  80                         data_ptr += sizeof(*pic_struct);
  81                         break;
  82                 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
  83                         data_ptr += sizeof(u32);
  84                         colour_info = (struct hfi_colour_space *)data_ptr;
  85                         event.colour_space = colour_info->colour_space;
  86                         data_ptr += sizeof(*colour_info);
  87                         break;
  88                 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
  89                         data_ptr += sizeof(u32);
  90                         event.entropy_mode = *(u32 *)data_ptr;
  91                         data_ptr += sizeof(u32);
  92                         break;
  93                 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
  94                         data_ptr += sizeof(u32);
  95                         bufreq = (struct hfi_buffer_requirements *)data_ptr;
  96                         event.buf_count = HFI_BUFREQ_COUNT_MIN(bufreq, ver);
  97                         data_ptr += sizeof(*bufreq);
  98                         break;
  99                 case HFI_INDEX_EXTRADATA_INPUT_CROP:
 100                         data_ptr += sizeof(u32);
 101                         crop = (struct hfi_extradata_input_crop *)data_ptr;
 102                         event.input_crop.left = crop->left;
 103                         event.input_crop.top = crop->top;
 104                         event.input_crop.width = crop->width;
 105                         event.input_crop.height = crop->height;
 106                         data_ptr += sizeof(*crop);
 107                         break;
 108                 default:
 109                         break;
 110                 }
 111                 num_properties_changed--;
 112         } while (num_properties_changed > 0);
 113 
 114 done:
 115         inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
 116 }
 117 
 118 static void event_release_buffer_ref(struct venus_core *core,
 119                                      struct venus_inst *inst,
 120                                      struct hfi_msg_event_notify_pkt *pkt)
 121 {
 122         struct hfi_event_data event = {0};
 123         struct hfi_msg_event_release_buffer_ref_pkt *data;
 124 
 125         data = (struct hfi_msg_event_release_buffer_ref_pkt *)
 126                 pkt->ext_event_data;
 127 
 128         event.event_type = HFI_EVENT_RELEASE_BUFFER_REFERENCE;
 129         event.packet_buffer = data->packet_buffer;
 130         event.extradata_buffer = data->extradata_buffer;
 131         event.tag = data->output_tag;
 132 
 133         inst->error = HFI_ERR_NONE;
 134         inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
 135 }
 136 
 137 static void event_sys_error(struct venus_core *core, u32 event,
 138                             struct hfi_msg_event_notify_pkt *pkt)
 139 {
 140         if (pkt)
 141                 dev_dbg(core->dev,
 142                         "sys error (session id:%x, data1:%x, data2:%x)\n",
 143                         pkt->shdr.session_id, pkt->event_data1,
 144                         pkt->event_data2);
 145 
 146         core->core_ops->event_notify(core, event);
 147 }
 148 
 149 static void
 150 event_session_error(struct venus_core *core, struct venus_inst *inst,
 151                     struct hfi_msg_event_notify_pkt *pkt)
 152 {
 153         struct device *dev = core->dev;
 154 
 155         dev_dbg(dev, "session error: event id:%x, session id:%x\n",
 156                 pkt->event_data1, pkt->shdr.session_id);
 157 
 158         if (!inst)
 159                 return;
 160 
 161         switch (pkt->event_data1) {
 162         /* non fatal session errors */
 163         case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
 164         case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
 165         case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
 166         case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
 167                 inst->error = HFI_ERR_NONE;
 168                 break;
 169         default:
 170                 dev_err(dev, "session error: event id:%x (%x), session id:%x\n",
 171                         pkt->event_data1, pkt->event_data2,
 172                         pkt->shdr.session_id);
 173 
 174                 inst->error = pkt->event_data1;
 175                 inst->ops->event_notify(inst, EVT_SESSION_ERROR, NULL);
 176                 break;
 177         }
 178 }
 179 
 180 static void hfi_event_notify(struct venus_core *core, struct venus_inst *inst,
 181                              void *packet)
 182 {
 183         struct hfi_msg_event_notify_pkt *pkt = packet;
 184 
 185         if (!packet)
 186                 return;
 187 
 188         switch (pkt->event_id) {
 189         case HFI_EVENT_SYS_ERROR:
 190                 event_sys_error(core, EVT_SYS_ERROR, pkt);
 191                 break;
 192         case HFI_EVENT_SESSION_ERROR:
 193                 event_session_error(core, inst, pkt);
 194                 break;
 195         case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
 196                 event_seq_changed(core, inst, pkt);
 197                 break;
 198         case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
 199                 event_release_buffer_ref(core, inst, pkt);
 200                 break;
 201         case HFI_EVENT_SESSION_PROPERTY_CHANGED:
 202                 break;
 203         default:
 204                 break;
 205         }
 206 }
 207 
 208 static void hfi_sys_init_done(struct venus_core *core, struct venus_inst *inst,
 209                               void *packet)
 210 {
 211         struct hfi_msg_sys_init_done_pkt *pkt = packet;
 212         int rem_bytes;
 213         u32 error;
 214 
 215         error = pkt->error_type;
 216         if (error != HFI_ERR_NONE)
 217                 goto done;
 218 
 219         if (!pkt->num_properties) {
 220                 error = HFI_ERR_SYS_INVALID_PARAMETER;
 221                 goto done;
 222         }
 223 
 224         rem_bytes = pkt->hdr.size - sizeof(*pkt) + sizeof(u32);
 225         if (rem_bytes <= 0) {
 226                 /* missing property data */
 227                 error = HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
 228                 goto done;
 229         }
 230 
 231         error = hfi_parser(core, inst, pkt->data, rem_bytes);
 232 
 233 done:
 234         core->error = error;
 235         complete(&core->done);
 236 }
 237 
 238 static void
 239 sys_get_prop_image_version(struct device *dev,
 240                            struct hfi_msg_sys_property_info_pkt *pkt)
 241 {
 242         int req_bytes;
 243 
 244         req_bytes = pkt->hdr.size - sizeof(*pkt);
 245 
 246         if (req_bytes < 128 || !pkt->data[1] || pkt->num_properties > 1)
 247                 /* bad packet */
 248                 return;
 249 
 250         dev_dbg(dev, "F/W version: %s\n", (u8 *)&pkt->data[1]);
 251 }
 252 
 253 static void hfi_sys_property_info(struct venus_core *core,
 254                                   struct venus_inst *inst, void *packet)
 255 {
 256         struct hfi_msg_sys_property_info_pkt *pkt = packet;
 257         struct device *dev = core->dev;
 258 
 259         if (!pkt->num_properties) {
 260                 dev_dbg(dev, "%s: no properties\n", __func__);
 261                 return;
 262         }
 263 
 264         switch (pkt->data[0]) {
 265         case HFI_PROPERTY_SYS_IMAGE_VERSION:
 266                 sys_get_prop_image_version(dev, pkt);
 267                 break;
 268         default:
 269                 dev_dbg(dev, "%s: unknown property data\n", __func__);
 270                 break;
 271         }
 272 }
 273 
 274 static void hfi_sys_rel_resource_done(struct venus_core *core,
 275                                       struct venus_inst *inst,
 276                                       void *packet)
 277 {
 278         struct hfi_msg_sys_release_resource_done_pkt *pkt = packet;
 279 
 280         core->error = pkt->error_type;
 281         complete(&core->done);
 282 }
 283 
 284 static void hfi_sys_ping_done(struct venus_core *core, struct venus_inst *inst,
 285                               void *packet)
 286 {
 287         struct hfi_msg_sys_ping_ack_pkt *pkt = packet;
 288 
 289         core->error = HFI_ERR_NONE;
 290 
 291         if (pkt->client_data != 0xbeef)
 292                 core->error = HFI_ERR_SYS_FATAL;
 293 
 294         complete(&core->done);
 295 }
 296 
 297 static void hfi_sys_idle_done(struct venus_core *core, struct venus_inst *inst,
 298                               void *packet)
 299 {
 300         dev_dbg(core->dev, "sys idle\n");
 301 }
 302 
 303 static void hfi_sys_pc_prepare_done(struct venus_core *core,
 304                                     struct venus_inst *inst, void *packet)
 305 {
 306         struct hfi_msg_sys_pc_prep_done_pkt *pkt = packet;
 307 
 308         dev_dbg(core->dev, "pc prepare done (error %x)\n", pkt->error_type);
 309 }
 310 
 311 static unsigned int
 312 session_get_prop_profile_level(struct hfi_msg_session_property_info_pkt *pkt,
 313                                struct hfi_profile_level *profile_level)
 314 {
 315         struct hfi_profile_level *hfi;
 316         u32 req_bytes;
 317 
 318         req_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
 319 
 320         if (!req_bytes || req_bytes % sizeof(struct hfi_profile_level))
 321                 /* bad packet */
 322                 return HFI_ERR_SESSION_INVALID_PARAMETER;
 323 
 324         hfi = (struct hfi_profile_level *)&pkt->data[1];
 325         profile_level->profile = hfi->profile;
 326         profile_level->level = hfi->level;
 327 
 328         return HFI_ERR_NONE;
 329 }
 330 
 331 static unsigned int
 332 session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt *pkt,
 333                          struct hfi_buffer_requirements *bufreq)
 334 {
 335         struct hfi_buffer_requirements *buf_req;
 336         u32 req_bytes;
 337         unsigned int idx = 0;
 338 
 339         req_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
 340 
 341         if (!req_bytes || req_bytes % sizeof(*buf_req) || !pkt->data[1])
 342                 /* bad packet */
 343                 return HFI_ERR_SESSION_INVALID_PARAMETER;
 344 
 345         buf_req = (struct hfi_buffer_requirements *)&pkt->data[1];
 346         if (!buf_req)
 347                 return HFI_ERR_SESSION_INVALID_PARAMETER;
 348 
 349         while (req_bytes) {
 350                 memcpy(&bufreq[idx], buf_req, sizeof(*bufreq));
 351                 idx++;
 352 
 353                 if (idx > HFI_BUFFER_TYPE_MAX)
 354                         return HFI_ERR_SESSION_INVALID_PARAMETER;
 355 
 356                 req_bytes -= sizeof(struct hfi_buffer_requirements);
 357                 buf_req++;
 358         }
 359 
 360         return HFI_ERR_NONE;
 361 }
 362 
 363 static void hfi_session_prop_info(struct venus_core *core,
 364                                   struct venus_inst *inst, void *packet)
 365 {
 366         struct hfi_msg_session_property_info_pkt *pkt = packet;
 367         struct device *dev = core->dev;
 368         union hfi_get_property *hprop = &inst->hprop;
 369         unsigned int error = HFI_ERR_NONE;
 370 
 371         if (!pkt->num_properties) {
 372                 error = HFI_ERR_SESSION_INVALID_PARAMETER;
 373                 dev_err(dev, "%s: no properties\n", __func__);
 374                 goto done;
 375         }
 376 
 377         switch (pkt->data[0]) {
 378         case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
 379                 memset(hprop->bufreq, 0, sizeof(hprop->bufreq));
 380                 error = session_get_prop_buf_req(pkt, hprop->bufreq);
 381                 break;
 382         case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
 383                 memset(&hprop->profile_level, 0, sizeof(hprop->profile_level));
 384                 error = session_get_prop_profile_level(pkt,
 385                                                        &hprop->profile_level);
 386                 break;
 387         case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
 388                 break;
 389         default:
 390                 dev_dbg(dev, "%s: unknown property id:%x\n", __func__,
 391                         pkt->data[0]);
 392                 return;
 393         }
 394 
 395 done:
 396         inst->error = error;
 397         complete(&inst->done);
 398 }
 399 
 400 static void hfi_session_init_done(struct venus_core *core,
 401                                   struct venus_inst *inst, void *packet)
 402 {
 403         struct hfi_msg_session_init_done_pkt *pkt = packet;
 404         int rem_bytes;
 405         u32 error;
 406 
 407         error = pkt->error_type;
 408         if (error != HFI_ERR_NONE)
 409                 goto done;
 410 
 411         if (!IS_V1(core))
 412                 goto done;
 413 
 414         rem_bytes = pkt->shdr.hdr.size - sizeof(*pkt) + sizeof(u32);
 415         if (rem_bytes <= 0) {
 416                 error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
 417                 goto done;
 418         }
 419 
 420         error = hfi_parser(core, inst, pkt->data, rem_bytes);
 421 done:
 422         inst->error = error;
 423         complete(&inst->done);
 424 }
 425 
 426 static void hfi_session_load_res_done(struct venus_core *core,
 427                                       struct venus_inst *inst, void *packet)
 428 {
 429         struct hfi_msg_session_load_resources_done_pkt *pkt = packet;
 430 
 431         inst->error = pkt->error_type;
 432         complete(&inst->done);
 433 }
 434 
 435 static void hfi_session_flush_done(struct venus_core *core,
 436                                    struct venus_inst *inst, void *packet)
 437 {
 438         struct hfi_msg_session_flush_done_pkt *pkt = packet;
 439 
 440         inst->error = pkt->error_type;
 441         complete(&inst->done);
 442 }
 443 
 444 static void hfi_session_etb_done(struct venus_core *core,
 445                                  struct venus_inst *inst, void *packet)
 446 {
 447         struct hfi_msg_session_empty_buffer_done_pkt *pkt = packet;
 448 
 449         inst->error = pkt->error_type;
 450         inst->ops->buf_done(inst, HFI_BUFFER_INPUT, pkt->input_tag,
 451                             pkt->filled_len, pkt->offset, 0, 0, 0);
 452 }
 453 
 454 static void hfi_session_ftb_done(struct venus_core *core,
 455                                  struct venus_inst *inst, void *packet)
 456 {
 457         u32 session_type = inst->session_type;
 458         u64 timestamp_us = 0;
 459         u32 timestamp_hi = 0, timestamp_lo = 0;
 460         unsigned int error;
 461         u32 flags = 0, hfi_flags = 0, offset = 0, filled_len = 0;
 462         u32 pic_type = 0, buffer_type = 0, output_tag = -1;
 463 
 464         if (session_type == VIDC_SESSION_TYPE_ENC) {
 465                 struct hfi_msg_session_fbd_compressed_pkt *pkt = packet;
 466 
 467                 timestamp_hi = pkt->time_stamp_hi;
 468                 timestamp_lo = pkt->time_stamp_lo;
 469                 hfi_flags = pkt->flags;
 470                 offset = pkt->offset;
 471                 filled_len = pkt->filled_len;
 472                 pic_type = pkt->picture_type;
 473                 output_tag = pkt->output_tag;
 474                 buffer_type = HFI_BUFFER_OUTPUT;
 475 
 476                 error = pkt->error_type;
 477         } else if (session_type == VIDC_SESSION_TYPE_DEC) {
 478                 struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt =
 479                         packet;
 480 
 481                 timestamp_hi = pkt->time_stamp_hi;
 482                 timestamp_lo = pkt->time_stamp_lo;
 483                 hfi_flags = pkt->flags;
 484                 offset = pkt->offset;
 485                 filled_len = pkt->filled_len;
 486                 pic_type = pkt->picture_type;
 487                 output_tag = pkt->output_tag;
 488 
 489                 if (pkt->stream_id == 0)
 490                         buffer_type = HFI_BUFFER_OUTPUT;
 491                 else if (pkt->stream_id == 1)
 492                         buffer_type = HFI_BUFFER_OUTPUT2;
 493 
 494                 error = pkt->error_type;
 495         } else {
 496                 error = HFI_ERR_SESSION_INVALID_PARAMETER;
 497         }
 498 
 499         if (buffer_type != HFI_BUFFER_OUTPUT &&
 500             buffer_type != HFI_BUFFER_OUTPUT2)
 501                 goto done;
 502 
 503         if (hfi_flags & HFI_BUFFERFLAG_EOS)
 504                 flags |= V4L2_BUF_FLAG_LAST;
 505 
 506         switch (pic_type) {
 507         case HFI_PICTURE_IDR:
 508         case HFI_PICTURE_I:
 509                 flags |= V4L2_BUF_FLAG_KEYFRAME;
 510                 break;
 511         case HFI_PICTURE_P:
 512                 flags |= V4L2_BUF_FLAG_PFRAME;
 513                 break;
 514         case HFI_PICTURE_B:
 515                 flags |= V4L2_BUF_FLAG_BFRAME;
 516                 break;
 517         case HFI_FRAME_NOTCODED:
 518         case HFI_UNUSED_PICT:
 519         case HFI_FRAME_YUV:
 520         default:
 521                 break;
 522         }
 523 
 524         if (!(hfi_flags & HFI_BUFFERFLAG_TIMESTAMPINVALID) && filled_len) {
 525                 timestamp_us = timestamp_hi;
 526                 timestamp_us = (timestamp_us << 32) | timestamp_lo;
 527         }
 528 
 529 done:
 530         inst->error = error;
 531         inst->ops->buf_done(inst, buffer_type, output_tag, filled_len,
 532                             offset, flags, hfi_flags, timestamp_us);
 533 }
 534 
 535 static void hfi_session_start_done(struct venus_core *core,
 536                                    struct venus_inst *inst, void *packet)
 537 {
 538         struct hfi_msg_session_start_done_pkt *pkt = packet;
 539 
 540         inst->error = pkt->error_type;
 541         complete(&inst->done);
 542 }
 543 
 544 static void hfi_session_stop_done(struct venus_core *core,
 545                                   struct venus_inst *inst, void *packet)
 546 {
 547         struct hfi_msg_session_stop_done_pkt *pkt = packet;
 548 
 549         inst->error = pkt->error_type;
 550         complete(&inst->done);
 551 }
 552 
 553 static void hfi_session_rel_res_done(struct venus_core *core,
 554                                      struct venus_inst *inst, void *packet)
 555 {
 556         struct hfi_msg_session_release_resources_done_pkt *pkt = packet;
 557 
 558         inst->error = pkt->error_type;
 559         complete(&inst->done);
 560 }
 561 
 562 static void hfi_session_rel_buf_done(struct venus_core *core,
 563                                      struct venus_inst *inst, void *packet)
 564 {
 565         struct hfi_msg_session_release_buffers_done_pkt *pkt = packet;
 566 
 567         inst->error = pkt->error_type;
 568         complete(&inst->done);
 569 }
 570 
 571 static void hfi_session_end_done(struct venus_core *core,
 572                                  struct venus_inst *inst, void *packet)
 573 {
 574         struct hfi_msg_session_end_done_pkt *pkt = packet;
 575 
 576         inst->error = pkt->error_type;
 577         complete(&inst->done);
 578 }
 579 
 580 static void hfi_session_abort_done(struct venus_core *core,
 581                                    struct venus_inst *inst, void *packet)
 582 {
 583         struct hfi_msg_sys_session_abort_done_pkt *pkt = packet;
 584 
 585         inst->error = pkt->error_type;
 586         complete(&inst->done);
 587 }
 588 
 589 static void hfi_session_get_seq_hdr_done(struct venus_core *core,
 590                                          struct venus_inst *inst, void *packet)
 591 {
 592         struct hfi_msg_session_get_sequence_hdr_done_pkt *pkt = packet;
 593 
 594         inst->error = pkt->error_type;
 595         complete(&inst->done);
 596 }
 597 
 598 struct hfi_done_handler {
 599         u32 pkt;
 600         u32 pkt_sz;
 601         u32 pkt_sz2;
 602         void (*done)(struct venus_core *, struct venus_inst *, void *);
 603         bool is_sys_pkt;
 604 };
 605 
 606 static const struct hfi_done_handler handlers[] = {
 607         {.pkt = HFI_MSG_EVENT_NOTIFY,
 608          .pkt_sz = sizeof(struct hfi_msg_event_notify_pkt),
 609          .done = hfi_event_notify,
 610         },
 611         {.pkt = HFI_MSG_SYS_INIT,
 612          .pkt_sz = sizeof(struct hfi_msg_sys_init_done_pkt),
 613          .done = hfi_sys_init_done,
 614          .is_sys_pkt = true,
 615         },
 616         {.pkt = HFI_MSG_SYS_PROPERTY_INFO,
 617          .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt),
 618          .done = hfi_sys_property_info,
 619          .is_sys_pkt = true,
 620         },
 621         {.pkt = HFI_MSG_SYS_RELEASE_RESOURCE,
 622          .pkt_sz = sizeof(struct hfi_msg_sys_release_resource_done_pkt),
 623          .done = hfi_sys_rel_resource_done,
 624          .is_sys_pkt = true,
 625         },
 626         {.pkt = HFI_MSG_SYS_PING_ACK,
 627          .pkt_sz = sizeof(struct hfi_msg_sys_ping_ack_pkt),
 628          .done = hfi_sys_ping_done,
 629          .is_sys_pkt = true,
 630         },
 631         {.pkt = HFI_MSG_SYS_IDLE,
 632          .pkt_sz = sizeof(struct hfi_msg_sys_idle_pkt),
 633          .done = hfi_sys_idle_done,
 634          .is_sys_pkt = true,
 635         },
 636         {.pkt = HFI_MSG_SYS_PC_PREP,
 637          .pkt_sz = sizeof(struct hfi_msg_sys_pc_prep_done_pkt),
 638          .done = hfi_sys_pc_prepare_done,
 639          .is_sys_pkt = true,
 640         },
 641         {.pkt = HFI_MSG_SYS_SESSION_INIT,
 642          .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt),
 643          .done = hfi_session_init_done,
 644         },
 645         {.pkt = HFI_MSG_SYS_SESSION_END,
 646          .pkt_sz = sizeof(struct hfi_msg_session_end_done_pkt),
 647          .done = hfi_session_end_done,
 648         },
 649         {.pkt = HFI_MSG_SESSION_LOAD_RESOURCES,
 650          .pkt_sz = sizeof(struct hfi_msg_session_load_resources_done_pkt),
 651          .done = hfi_session_load_res_done,
 652         },
 653         {.pkt = HFI_MSG_SESSION_START,
 654          .pkt_sz = sizeof(struct hfi_msg_session_start_done_pkt),
 655          .done = hfi_session_start_done,
 656         },
 657         {.pkt = HFI_MSG_SESSION_STOP,
 658          .pkt_sz = sizeof(struct hfi_msg_session_stop_done_pkt),
 659          .done = hfi_session_stop_done,
 660         },
 661         {.pkt = HFI_MSG_SYS_SESSION_ABORT,
 662          .pkt_sz = sizeof(struct hfi_msg_sys_session_abort_done_pkt),
 663          .done = hfi_session_abort_done,
 664         },
 665         {.pkt = HFI_MSG_SESSION_EMPTY_BUFFER,
 666          .pkt_sz = sizeof(struct hfi_msg_session_empty_buffer_done_pkt),
 667          .done = hfi_session_etb_done,
 668         },
 669         {.pkt = HFI_MSG_SESSION_FILL_BUFFER,
 670          .pkt_sz = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt),
 671          .pkt_sz2 = sizeof(struct hfi_msg_session_fbd_compressed_pkt),
 672          .done = hfi_session_ftb_done,
 673         },
 674         {.pkt = HFI_MSG_SESSION_FLUSH,
 675          .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt),
 676          .done = hfi_session_flush_done,
 677         },
 678         {.pkt = HFI_MSG_SESSION_PROPERTY_INFO,
 679          .pkt_sz = sizeof(struct hfi_msg_session_property_info_pkt),
 680          .done = hfi_session_prop_info,
 681         },
 682         {.pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,
 683          .pkt_sz = sizeof(struct hfi_msg_session_release_resources_done_pkt),
 684          .done = hfi_session_rel_res_done,
 685         },
 686         {.pkt = HFI_MSG_SESSION_GET_SEQUENCE_HEADER,
 687          .pkt_sz = sizeof(struct hfi_msg_session_get_sequence_hdr_done_pkt),
 688          .done = hfi_session_get_seq_hdr_done,
 689         },
 690         {.pkt = HFI_MSG_SESSION_RELEASE_BUFFERS,
 691          .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt),
 692          .done = hfi_session_rel_buf_done,
 693         },
 694 };
 695 
 696 void hfi_process_watchdog_timeout(struct venus_core *core)
 697 {
 698         event_sys_error(core, EVT_SYS_WATCHDOG_TIMEOUT, NULL);
 699 }
 700 
 701 static struct venus_inst *to_instance(struct venus_core *core, u32 session_id)
 702 {
 703         struct venus_inst *inst;
 704 
 705         mutex_lock(&core->lock);
 706         list_for_each_entry(inst, &core->instances, list)
 707                 if (hash32_ptr(inst) == session_id) {
 708                         mutex_unlock(&core->lock);
 709                         return inst;
 710                 }
 711         mutex_unlock(&core->lock);
 712 
 713         return NULL;
 714 }
 715 
 716 u32 hfi_process_msg_packet(struct venus_core *core, struct hfi_pkt_hdr *hdr)
 717 {
 718         const struct hfi_done_handler *handler;
 719         struct device *dev = core->dev;
 720         struct venus_inst *inst;
 721         bool found = false;
 722         unsigned int i;
 723 
 724         for (i = 0; i < ARRAY_SIZE(handlers); i++) {
 725                 handler = &handlers[i];
 726                 if (handler->pkt != hdr->pkt_type)
 727                         continue;
 728                 found = true;
 729                 break;
 730         }
 731 
 732         if (!found)
 733                 return hdr->pkt_type;
 734 
 735         if (hdr->size && hdr->size < handler->pkt_sz &&
 736             hdr->size < handler->pkt_sz2) {
 737                 dev_err(dev, "bad packet size (%d should be %d, pkt type:%x)\n",
 738                         hdr->size, handler->pkt_sz, hdr->pkt_type);
 739 
 740                 return hdr->pkt_type;
 741         }
 742 
 743         if (handler->is_sys_pkt) {
 744                 inst = NULL;
 745         } else {
 746                 struct hfi_session_pkt *pkt;
 747 
 748                 pkt = (struct hfi_session_pkt *)hdr;
 749                 inst = to_instance(core, pkt->shdr.session_id);
 750 
 751                 if (!inst)
 752                         dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n",
 753                                  pkt->shdr.session_id,
 754                                  handler ? handler->pkt : 0);
 755 
 756                 /*
 757                  * Event of type HFI_EVENT_SYS_ERROR will not have any session
 758                  * associated with it
 759                  */
 760                 if (!inst && hdr->pkt_type != HFI_MSG_EVENT_NOTIFY) {
 761                         dev_err(dev, "got invalid session id:%x\n",
 762                                 pkt->shdr.session_id);
 763                         goto invalid_session;
 764                 }
 765         }
 766 
 767         handler->done(core, inst, hdr);
 768 
 769 invalid_session:
 770         return hdr->pkt_type;
 771 }

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