123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
- */
- #include "msm_cvp_common.h"
- #include "cvp_hfi_api.h"
- #include "msm_cvp_debug.h"
- #include "msm_cvp_core.h"
- #include "msm_cvp_dsp.h"
- #include "cvp_comm_def.h"
- #ifdef CVP_SYNX_ENABLED
- static int cvp_sess_init_synx_v2(struct msm_cvp_inst *inst)
- {
- struct synx_initialization_params params = { 0 };
- params.name = "cvp-kernel-client";
- params.id = SYNX_CLIENT_EVA_CTX0;
- inst->synx_session_id = synx_initialize(¶ms);
- if (IS_ERR_OR_NULL(&inst->synx_session_id)) {
- dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__);
- return -EFAULT;
- }
- return 0;
- }
- static int cvp_sess_deinit_synx_v2(struct msm_cvp_inst *inst)
- {
- if (!inst) {
- dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n");
- return -EINVAL;
- }
- synx_uninitialize(inst->synx_session_id);
- return 0;
- }
- static void cvp_dump_fence_queue_v2(struct msm_cvp_inst *inst)
- {
- struct cvp_fence_queue *q;
- struct cvp_fence_command *f;
- struct synx_session *ssid;
- int i;
- q = &inst->fence_cmd_queue;
- ssid = inst->synx_session_id;
- mutex_lock(&q->lock);
- dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %pK\n",
- hash32_ptr(inst->session), q->mode, ssid);
- dprintk(CVP_WARN, "fence cmdq wait list:\n");
- list_for_each_entry(f, &q->wait_list, list) {
- dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type);
- for (i = 0; i < f->output_index; i++)
- dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n",
- i, f->synx[i],
- synx_get_status(ssid, f->synx[i]));
- }
- dprintk(CVP_WARN, "fence cmdq schedule list:\n");
- list_for_each_entry(f, &q->sched_list, list) {
- dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type);
- for (i = 0; i < f->output_index; i++)
- dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n",
- i, f->synx[i],
- synx_get_status(ssid, f->synx[i]));
- }
- mutex_unlock(&q->lock);
- }
- static int cvp_import_synx_v2(struct msm_cvp_inst *inst,
- struct cvp_fence_command *fc,
- u32 *fence)
- {
- int rc = 0, rr = 0;
- int i;
- struct eva_kmd_fence *fs;
- struct synx_import_params params = {0};
- u32 h_synx;
- struct synx_session *ssid;
- fs = (struct eva_kmd_fence *)fence;
- ssid = inst->synx_session_id;
- for (i = 0; i < fc->num_fences; ++i) {
- h_synx = fs[i].h_synx;
- if (h_synx) {
- params.type = SYNX_IMPORT_INDV_PARAMS;
- params.indv.fence = &h_synx;
- params.indv.flags = SYNX_IMPORT_SYNX_FENCE
- | SYNX_IMPORT_LOCAL_FENCE;
- params.indv.new_h_synx = &fc->synx[i];
- rc = synx_import(ssid, ¶ms);
- if (rc) {
- dprintk(CVP_ERR,
- "%s: %u synx_import failed\n",
- __func__, h_synx);
- rr = rc;
- }
- }
- }
- return rr;
- }
- static int cvp_release_synx_v2(struct msm_cvp_inst *inst,
- struct cvp_fence_command *fc)
- {
- int rc = 0;
- int i;
- u32 h_synx;
- struct synx_session *ssid;
- ssid = inst->synx_session_id;
- for (i = 0; i < fc->num_fences; ++i) {
- h_synx = fc->synx[i];
- if (h_synx) {
- rc = synx_release(ssid, h_synx);
- if (rc)
- dprintk(CVP_ERR,
- "%s: synx_release %d, %d failed\n",
- __func__, h_synx, i);
- }
- }
- return rc;
- }
- static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst,
- enum cvp_synx_type type,
- struct cvp_fence_command *fc,
- int synx_state)
- {
- int rc = 0;
- int i;
- u32 h_synx;
- struct synx_session *ssid;
- int start = 0, end = 0;
- ssid = inst->synx_session_id;
- if (type == CVP_INPUT_SYNX) {
- start = 0;
- end = fc->output_index;
- } else if (type == CVP_OUTPUT_SYNX) {
- start = fc->output_index;
- end = fc->num_fences;
- } else {
- dprintk(CVP_ERR, "%s Incorrect synx type\n", __func__);
- return -EINVAL;
- }
- for (i = start; i < end; ++i) {
- h_synx = fc->synx[i];
- if (h_synx) {
- rc = synx_signal(ssid, h_synx, synx_state);
- dprintk(CVP_SYNX, "Cancel synx %d session %llx\n",
- h_synx, inst);
- if (rc)
- dprintk(CVP_ERR,
- "%s: synx_signal %d %d %d failed\n",
- __func__, h_synx, i, synx_state);
- }
- }
- return rc;
- }
- static int cvp_cancel_synx_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type,
- struct cvp_fence_command *fc, int synx_state)
- {
- return cvp_cancel_synx_impl(inst, type, fc, synx_state);
- }
- static int cvp_wait_synx(struct synx_session *ssid, u32 *synx, u32 num_synx,
- u32 *synx_state)
- {
- int i = 0, rc = 0;
- unsigned long timeout_ms = 2000;
- u32 h_synx;
- while (i < num_synx) {
- h_synx = synx[i];
- if (h_synx) {
- rc = synx_wait(ssid, h_synx, timeout_ms);
- if (rc) {
- *synx_state = synx_get_status(ssid, h_synx);
- if(*synx_state == SYNX_STATE_SIGNALED_SUCCESS)
- {
- dprintk(CVP_SYNX, "%s: SYNX SIGNAl STATE SUCCESS \n", __func__);
- rc=0;
- i++;
- continue;
- }
- else if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) {
- dprintk(CVP_SYNX,
- "%s: synx_wait %d cancel %d state %d\n",
- current->comm, i, rc, *synx_state);
- } else {
- dprintk(CVP_ERR,
- "%s: synx_wait %d failed %d state %d\n",
- current->comm, i, rc, *synx_state);
- *synx_state = SYNX_STATE_SIGNALED_CANCEL;
- }
- return rc;
- } else {
- rc = 0; /* SYNX_STATE_SIGNALED_SUCCESS = 2 */
- }
- dprintk(CVP_SYNX, "Wait synx %u returned succes\n",
- h_synx);
- }
- ++i;
- }
- return rc;
- }
- static int cvp_signal_synx(struct synx_session *ssid, u32 *synx, u32 num_synx,
- u32 synx_state)
- {
- int i = 0, rc = 0;
- u32 h_synx;
- while (i < num_synx) {
- h_synx = synx[i];
- if (h_synx) {
- rc = synx_signal(ssid, h_synx, synx_state);
- if (rc) {
- dprintk(CVP_ERR,
- "%s: synx_signal %u %d failed\n",
- current->comm, h_synx, i);
- synx_state = SYNX_STATE_SIGNALED_CANCEL;
- }
- dprintk(CVP_SYNX, "Signaled synx %u state %d\n",
- h_synx, synx_state);
- }
- ++i;
- }
- return rc;
- }
- static int cvp_synx_ops_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type,
- struct cvp_fence_command *fc, u32 *synx_state)
- {
- struct synx_session *ssid;
- if (fc->signature == 0xB0BABABE)
- return 0;
- ssid = inst->synx_session_id;
- if (type == CVP_INPUT_SYNX) {
- return cvp_wait_synx(ssid, fc->synx, fc->output_index,
- synx_state);
- } else if (type == CVP_OUTPUT_SYNX) {
- return cvp_signal_synx(ssid, &fc->synx[fc->output_index],
- (fc->num_fences - fc->output_index),
- *synx_state);
- } else {
- dprintk(CVP_ERR, "%s Incorrect SYNX type\n", __func__);
- return -EINVAL;
- }
- }
- static struct msm_cvp_synx_ops cvp_synx = {
- .cvp_sess_init_synx = cvp_sess_init_synx_v2,
- .cvp_sess_deinit_synx = cvp_sess_deinit_synx_v2,
- .cvp_release_synx = cvp_release_synx_v2,
- .cvp_import_synx = cvp_import_synx_v2,
- .cvp_synx_ops = cvp_synx_ops_v2,
- .cvp_cancel_synx = cvp_cancel_synx_v2,
- .cvp_dump_fence_queue = cvp_dump_fence_queue_v2,
- };
- #else
- static int cvp_sess_init_synx_stub(struct msm_cvp_inst *inst)
- {
- return 0;
- }
- static int cvp_sess_deinit_synx_stub(struct msm_cvp_inst *inst)
- {
- return 0;
- }
- static int cvp_release_synx_stub(struct msm_cvp_inst *inst,
- struct cvp_fence_command *fc)
- {
- return 0;
- }
- static int cvp_import_synx_stub(struct msm_cvp_inst *inst,
- struct cvp_fence_command *fc,
- u32 *fence)
- {
- return 0;
- }
- static int cvp_synx_ops_stub(struct msm_cvp_inst *inst, enum cvp_synx_type type,
- struct cvp_fence_command *fc, u32 *synx_state)
- {
- return 0;
- }
- static int cvp_cancel_synx_stub(struct msm_cvp_inst *inst, enum cvp_synx_type type,
- struct cvp_fence_command *fc, int synx_state)
- {
- return 0;
- }
- static void cvp_dump_fence_queue_stub(struct msm_cvp_inst *inst)
- {
- }
- static struct msm_cvp_synx_ops cvp_synx = {
- .cvp_sess_init_synx = cvp_sess_init_synx_stub,
- .cvp_sess_deinit_synx = cvp_sess_deinit_synx_stub,
- .cvp_release_synx = cvp_release_synx_stub,
- .cvp_import_synx = cvp_import_synx_stub,
- .cvp_synx_ops = cvp_synx_ops_stub,
- .cvp_cancel_synx = cvp_cancel_synx_stub,
- .cvp_dump_fence_queue = cvp_dump_fence_queue_stub,
- };
- #endif /* End of CVP_SYNX_ENABLED */
- void cvp_synx_ftbl_init(struct msm_cvp_core *core)
- {
- if (!core)
- return;
- /* Synx API version check below if needed */
- core->synx_ftbl = &cvp_synx;
- }
|