mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-06 20:03:33 -04:00
msm: cvp: Optimize synX handling in cvp driver
Make synX handling in kernel independent of CVP features. It also simplified handling logic. Change-Id: I598d2c78f0fea4463c5801b5db945b74c071ebab Signed-off-by: George Shen <sqiao@codeaurora.org>
This commit is contained in:
parent
f115a8d721
commit
da53e790e2
10 changed files with 784 additions and 763 deletions
|
|
@ -17,6 +17,7 @@ msm-cvp-objs := cvp.o \
|
|||
cvp_core_hfi.o \
|
||||
msm_cvp_clocks.o \
|
||||
msm_cvp_dsp.o \
|
||||
msm_cvp_buf.o
|
||||
msm_cvp_buf.o \
|
||||
msm_cvp_synx.o
|
||||
|
||||
obj-$(CONFIG_MSM_CVP) := msm-cvp.o
|
||||
|
|
|
|||
24
drivers/media/platform/msm/cvp/cvp_comm_def.h
Normal file
24
drivers/media/platform/msm/cvp/cvp_comm_def.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_COMM_DEF_H_
|
||||
#define _MSM_COMM_DEF_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
enum op_mode {
|
||||
OP_NORMAL,
|
||||
OP_DRAINING,
|
||||
OP_FLUSH,
|
||||
OP_INVALID,
|
||||
};
|
||||
|
||||
enum queue_state {
|
||||
QUEUE_INIT,
|
||||
QUEUE_ACTIVE = 1,
|
||||
QUEUE_STOP = 2,
|
||||
QUEUE_INVALID,
|
||||
};
|
||||
#endif
|
||||
|
|
@ -275,19 +275,16 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int cvp_fence_dme(struct msm_cvp_inst *inst, u32 *synx,
|
||||
static int cvp_fence_dme(struct msm_cvp_inst *inst,
|
||||
struct cvp_fence_command *fc,
|
||||
struct cvp_hfi_cmd_session_hdr *pkt)
|
||||
{
|
||||
int i;
|
||||
int rc = 0;
|
||||
unsigned long timeout;
|
||||
int h_synx;
|
||||
u64 ktid;
|
||||
unsigned long timeout_ms = 1000;
|
||||
int synx_state = SYNX_STATE_SIGNALED_SUCCESS;
|
||||
struct cvp_hfi_device *hdev;
|
||||
struct cvp_session_queue *sq;
|
||||
struct synx_session ssid;
|
||||
u32 hfi_err = HFI_ERR_NONE;
|
||||
struct cvp_hfi_msg_session_hdr *hdr;
|
||||
|
||||
|
|
@ -295,29 +292,10 @@ static int cvp_fence_dme(struct msm_cvp_inst *inst, u32 *synx,
|
|||
|
||||
hdev = inst->core->device;
|
||||
sq = &inst->session_queue_fence;
|
||||
ssid = inst->synx_session_id;
|
||||
ktid = pkt->client_data.kdata;
|
||||
|
||||
i = 0;
|
||||
while (i < HFI_DME_BUF_NUM - 1) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_wait(ssid, h_synx, timeout_ms);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s %s: synx_wait %d failed\n",
|
||||
current->comm, __func__, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
/*
|
||||
* Increase loop count to skip fence
|
||||
* waiting on downscale image where i == 1.
|
||||
*/
|
||||
if (i == FENCE_DME_ICA_ENABLED_IDX)
|
||||
++i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state))
|
||||
goto exit;
|
||||
|
||||
rc = call_hfi_op(hdev, session_send, (void *)inst->session,
|
||||
(struct cvp_kmd_hfi_packet *)pkt);
|
||||
|
|
@ -354,40 +332,21 @@ static int cvp_fence_dme(struct msm_cvp_inst *inst, u32 *synx,
|
|||
}
|
||||
|
||||
exit:
|
||||
if (synx[FENCE_DME_ICA_ENABLED_IDX]) {
|
||||
h_synx = synx[FENCE_DME_DS_IDX];
|
||||
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s %s: synx_signal %d failed\n",
|
||||
current->comm, __func__, FENCE_DME_DS_IDX);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
h_synx = synx[FENCE_DME_OUTPUT_IDX];
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR, "%s %s: synx_signal %d failed\n",
|
||||
current->comm, __func__, FENCE_DME_OUTPUT_IDX);
|
||||
rc = cvp_synx_ops(inst, CVP_OUTPUT_SYNX, fc, &synx_state);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_fence_proc(struct msm_cvp_inst *inst, u32 *synx,
|
||||
static int cvp_fence_proc(struct msm_cvp_inst *inst,
|
||||
struct cvp_fence_command *fc,
|
||||
struct cvp_hfi_cmd_session_hdr *pkt)
|
||||
{
|
||||
int i;
|
||||
int rc = 0;
|
||||
unsigned long timeout;
|
||||
int h_synx;
|
||||
u64 ktid;
|
||||
unsigned long timeout_ms = 1000;
|
||||
int synx_state = SYNX_STATE_SIGNALED_SUCCESS;
|
||||
struct cvp_hfi_device *hdev;
|
||||
struct cvp_session_queue *sq;
|
||||
struct synx_session ssid;
|
||||
u32 in, out;
|
||||
u32 hfi_err = HFI_ERR_NONE;
|
||||
struct cvp_hfi_msg_session_hdr *hdr;
|
||||
|
||||
|
|
@ -395,34 +354,10 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, u32 *synx,
|
|||
|
||||
hdev = inst->core->device;
|
||||
sq = &inst->session_queue_fence;
|
||||
ssid = inst->synx_session_id;
|
||||
ktid = pkt->client_data.kdata;
|
||||
|
||||
in = synx[0] >> 16;
|
||||
out = synx[0] & 0xFFFF;
|
||||
|
||||
i = 1;
|
||||
while (i <= in) {
|
||||
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_CANCEL) {
|
||||
dprintk(CVP_DBG,
|
||||
"%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_ERROR;
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state))
|
||||
goto exit;
|
||||
|
||||
rc = call_hfi_op(hdev, session_send, (void *)inst->session,
|
||||
(struct cvp_kmd_hfi_packet *)pkt);
|
||||
|
|
@ -455,19 +390,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, u32 *synx,
|
|||
}
|
||||
|
||||
exit:
|
||||
i = in + 1;
|
||||
while (i <= in + out) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: synx_signal %d failed\n",
|
||||
current->comm, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
rc = cvp_synx_ops(inst, CVP_OUTPUT_SYNX, fc, &synx_state);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -498,119 +421,6 @@ static void cvp_free_fence_data(struct cvp_fence_command *f)
|
|||
f = NULL;
|
||||
}
|
||||
|
||||
static int cvp_import_synx(struct msm_cvp_inst *inst, u32 type, u32 *fence,
|
||||
u32 *synx)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
int start = 0, end = 0;
|
||||
struct cvp_fence_type *f;
|
||||
struct synx_import_params params;
|
||||
s32 h_synx;
|
||||
struct synx_session ssid;
|
||||
|
||||
f = (struct cvp_fence_type *)fence;
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
switch (type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
{
|
||||
start = 0;
|
||||
end = HFI_DME_BUF_NUM;
|
||||
break;
|
||||
}
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
{
|
||||
u32 in = fence[0];
|
||||
u32 out = fence[1];
|
||||
|
||||
if (in > MAX_HFI_FENCE_SIZE || out > MAX_HFI_FENCE_SIZE
|
||||
|| in > MAX_HFI_FENCE_SIZE - out) {
|
||||
dprintk(CVP_ERR, "%s: failed!\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
synx[0] = (in << 16) | out;
|
||||
start = 1;
|
||||
end = in + out + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown fence type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = f[i].h_synx;
|
||||
|
||||
if (h_synx) {
|
||||
params.h_synx = h_synx;
|
||||
params.secure_key = f[i].secure_key;
|
||||
params.new_h_synx = &synx[i];
|
||||
|
||||
rc = synx_import(ssid, ¶ms);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_import failed\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_release_synx(struct msm_cvp_inst *inst, u32 type, u32 *synx)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
s32 h_synx;
|
||||
struct synx_session ssid;
|
||||
int start = 0, end = 0;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
switch (type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
{
|
||||
start = 0;
|
||||
end = HFI_DME_BUF_NUM;
|
||||
|
||||
break;
|
||||
}
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
{
|
||||
u32 in = synx[0] >> 16;
|
||||
u32 out = synx[0] & 0xFFFF;
|
||||
|
||||
start = 1;
|
||||
end = in + out + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown fence type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_release(ssid, h_synx);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_release %d failed\n",
|
||||
__func__, i);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_fence_thread(void *data)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -653,10 +463,10 @@ wait:
|
|||
|
||||
switch (f->type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
rc = cvp_fence_dme(inst, synx, pkt);
|
||||
rc = cvp_fence_dme(inst, f, pkt);
|
||||
break;
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
rc = cvp_fence_proc(inst, synx, pkt);
|
||||
rc = cvp_fence_proc(inst, f, pkt);
|
||||
break;
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown hfi cmd type 0x%x\n",
|
||||
|
|
@ -667,7 +477,7 @@ wait:
|
|||
}
|
||||
|
||||
mutex_lock(&q->lock);
|
||||
cvp_release_synx(inst, f->type, synx);
|
||||
cvp_release_synx(inst, f);
|
||||
list_del_init(&f->list);
|
||||
mutex_unlock(&q->lock);
|
||||
|
||||
|
|
@ -690,6 +500,8 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst,
|
|||
int rc = 0;
|
||||
int idx;
|
||||
struct cvp_kmd_hfi_fence_packet *fence_pkt;
|
||||
struct cvp_kmd_hfi_synx_packet *synx_pkt;
|
||||
struct cvp_kmd_fence_ctrl *kfc;
|
||||
struct cvp_hfi_cmd_session_hdr *pkt;
|
||||
unsigned int offset, buf_num, in_offset, in_buf_num;
|
||||
struct msm_cvp_inst *s;
|
||||
|
|
@ -724,7 +536,6 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst,
|
|||
|
||||
fence_pkt = &arg->data.hfi_fence_pkt;
|
||||
pkt = (struct cvp_hfi_cmd_session_hdr *)&fence_pkt->pkt_data;
|
||||
fence = (u32 *)&fence_pkt->fence_data;
|
||||
idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)pkt);
|
||||
|
||||
if (idx < 0 || pkt->size > MAX_HFI_FENCE_OFFSET) {
|
||||
|
|
@ -751,16 +562,29 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst,
|
|||
goto exit;
|
||||
|
||||
f->type = cvp_hfi_defs[idx].type;
|
||||
f->frame_id = arg->data.hfi_fence_pkt.frame_id;
|
||||
f->mode = OP_NORMAL;
|
||||
|
||||
synx_pkt = &arg->data.hfi_synx_pkt;
|
||||
if (synx_pkt->fence_data[0] != 0xFEEDFACE) {
|
||||
fence = (u32 *)&fence_pkt->fence_data;
|
||||
f->frame_id = arg->data.hfi_fence_pkt.frame_id;
|
||||
} else {
|
||||
kfc = &synx_pkt->fc;
|
||||
fence = (u32 *)&kfc->fences;
|
||||
f->frame_id = kfc->frame_id;
|
||||
f->signature = 0xFEEDFACE;
|
||||
f->num_fences = kfc->num_fences;
|
||||
f->output_index = kfc->output_index;
|
||||
}
|
||||
|
||||
|
||||
dprintk(CVP_DBG, "%s: frameID %llu\n", __func__, f->frame_id);
|
||||
|
||||
memcpy(f->pkt, pkt, pkt->size);
|
||||
|
||||
f->pkt->client_data.kdata |= FENCE_BIT;
|
||||
|
||||
rc = cvp_import_synx(inst, f->type, fence, f->synx);
|
||||
rc = cvp_import_synx(inst, f, fence);
|
||||
if (rc) {
|
||||
kfree(f);
|
||||
goto exit;
|
||||
|
|
@ -890,77 +714,6 @@ static void aggregate_power_update(struct msm_cvp_core *core,
|
|||
rt_pwr->bw_sum += bw_sum[1];
|
||||
}
|
||||
|
||||
|
||||
static void aggregate_power_request(struct msm_cvp_core *core,
|
||||
struct cvp_power_level *nrt_pwr,
|
||||
struct cvp_power_level *rt_pwr,
|
||||
unsigned int max_clk_rate)
|
||||
{
|
||||
struct msm_cvp_inst *inst;
|
||||
int i;
|
||||
unsigned long core_sum[2] = {0}, ctlr_sum[2] = {0}, fw_sum[2] = {0};
|
||||
unsigned long op_core_max[2] = {0}, op_ctlr_max[2] = {0};
|
||||
unsigned long op_fw_max[2] = {0}, bw_sum[2] = {0}, op_bw_max[2] = {0};
|
||||
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
if (inst->state == MSM_CVP_CORE_INVALID ||
|
||||
inst->state == MSM_CVP_CORE_UNINIT ||
|
||||
is_subblock_profile_existed(inst))
|
||||
continue;
|
||||
if (inst->prop.priority <= CVP_RT_PRIO_THRESHOLD) {
|
||||
/* Non-realtime session use index 0 */
|
||||
i = 0;
|
||||
} else {
|
||||
i = 1;
|
||||
}
|
||||
dprintk(CVP_PROF, "pwrReq sess %pK core %u ctl %u fw %u\n",
|
||||
inst, inst->power.clock_cycles_a,
|
||||
inst->power.clock_cycles_b,
|
||||
inst->power.reserved[0]);
|
||||
dprintk(CVP_PROF, "pwrReq op_core %u op_ctl %u op_fw %u\n",
|
||||
inst->power.reserved[1],
|
||||
inst->power.reserved[2],
|
||||
inst->power.reserved[3]);
|
||||
|
||||
core_sum[i] += inst->power.clock_cycles_a;
|
||||
ctlr_sum[i] += inst->power.clock_cycles_b;
|
||||
fw_sum[i] += inst->power.reserved[0];
|
||||
op_core_max[i] =
|
||||
(op_core_max[i] >= inst->power.reserved[1]) ?
|
||||
op_core_max[i] : inst->power.reserved[1];
|
||||
op_ctlr_max[i] =
|
||||
(op_ctlr_max[i] >= inst->power.reserved[2]) ?
|
||||
op_ctlr_max[i] : inst->power.reserved[2];
|
||||
op_fw_max[i] =
|
||||
(op_fw_max[i] >= inst->power.reserved[3]) ?
|
||||
op_fw_max[i] : inst->power.reserved[3];
|
||||
bw_sum[i] += inst->power.ddr_bw;
|
||||
op_bw_max[i] =
|
||||
(op_bw_max[i] >= inst->power.reserved[4]) ?
|
||||
op_bw_max[i] : inst->power.reserved[4];
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
core_sum[i] = max_3(core_sum[i], ctlr_sum[i], fw_sum[i]);
|
||||
op_core_max[i] = max_3(op_core_max[i],
|
||||
op_ctlr_max[i], op_fw_max[i]);
|
||||
op_core_max[i] =
|
||||
(op_core_max[i] > max_clk_rate) ?
|
||||
max_clk_rate : op_core_max[i];
|
||||
bw_sum[i] = (bw_sum[i] >= op_bw_max[i]) ?
|
||||
bw_sum[i] : op_bw_max[i];
|
||||
}
|
||||
|
||||
nrt_pwr->core_sum += core_sum[0];
|
||||
nrt_pwr->op_core_sum = (nrt_pwr->op_core_sum >= op_core_max[0]) ?
|
||||
nrt_pwr->op_core_sum : op_core_max[0];
|
||||
nrt_pwr->bw_sum += bw_sum[0];
|
||||
rt_pwr->core_sum += core_sum[1];
|
||||
rt_pwr->op_core_sum = (rt_pwr->op_core_sum >= op_core_max[1]) ?
|
||||
rt_pwr->op_core_sum : op_core_max[1];
|
||||
rt_pwr->bw_sum += bw_sum[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* adjust_bw_freqs(): calculate CVP clock freq and bw required to sustain
|
||||
* required use case.
|
||||
|
|
@ -999,10 +752,6 @@ static int adjust_bw_freqs(void)
|
|||
max_bw = bus->range[1];
|
||||
min_bw = max_bw/10;
|
||||
|
||||
aggregate_power_request(core, &nrt_pwr, &rt_pwr, cvp_max_rate);
|
||||
dprintk(CVP_DBG, "PwrReq nrt %u %u rt %u %u\n",
|
||||
nrt_pwr.core_sum, nrt_pwr.op_core_sum,
|
||||
rt_pwr.core_sum, rt_pwr.op_core_sum);
|
||||
aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate);
|
||||
dprintk(CVP_DBG, "PwrUpdate nrt %u %u rt %u %u\n",
|
||||
nrt_pwr.core_sum, nrt_pwr.op_core_sum,
|
||||
|
|
@ -1062,64 +811,6 @@ static int adjust_bw_freqs(void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use of cvp_kmd_request_power structure
|
||||
* clock_cycles_a: CVP core clock freq
|
||||
* clock_cycles_b: CVP controller clock freq
|
||||
* ddr_bw: b/w vote in Bps
|
||||
* reserved[0]: CVP firmware required clock freq
|
||||
* reserved[1]: CVP core operational clock freq
|
||||
* reserved[2]: CVP controller operational clock freq
|
||||
* reserved[3]: CVP firmware operational clock freq
|
||||
* reserved[4]: CVP operational b/w vote
|
||||
*
|
||||
* session's power record only saves normalized freq or b/w vote
|
||||
*/
|
||||
static int msm_cvp_request_power(struct msm_cvp_inst *inst,
|
||||
struct cvp_kmd_request_power *power)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_core *core;
|
||||
struct msm_cvp_inst *s;
|
||||
|
||||
if (!inst || !power) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s = cvp_get_inst_validate(inst->core, inst);
|
||||
if (!s)
|
||||
return -ECONNRESET;
|
||||
|
||||
inst->cur_cmd_type = CVP_KMD_REQUEST_POWER;
|
||||
core = inst->core;
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
|
||||
memcpy(&inst->power, power, sizeof(*power));
|
||||
|
||||
/* Normalize CVP controller clock freqs */
|
||||
inst->power.clock_cycles_b = div_by_1dot5(inst->power.clock_cycles_b);
|
||||
inst->power.reserved[0] = div_by_1dot5(inst->power.reserved[0]);
|
||||
inst->power.reserved[2] = div_by_1dot5(inst->power.reserved[2]);
|
||||
inst->power.reserved[3] = div_by_1dot5(inst->power.reserved[3]);
|
||||
|
||||
/* Convert bps to KBps */
|
||||
inst->power.ddr_bw = inst->power.ddr_bw >> 10;
|
||||
|
||||
rc = adjust_bw_freqs();
|
||||
if (rc) {
|
||||
memset(&inst->power, 0x0, sizeof(inst->power));
|
||||
dprintk(CVP_ERR, "Instance %pK power request out of range\n");
|
||||
}
|
||||
|
||||
mutex_unlock(&core->lock);
|
||||
inst->cur_cmd_type = 0;
|
||||
cvp_put_inst(s);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cvp_update_power(struct msm_cvp_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -1423,7 +1114,7 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst,
|
|||
struct cvp_kmd_sys_properties *props = &arg->data.sys_properties;
|
||||
struct cvp_hfi_device *hdev;
|
||||
struct iris_hfi_device *hfi;
|
||||
int rc = 0;
|
||||
int i, rc = 0;
|
||||
|
||||
if (!inst || !inst->core || !inst->core->device) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
|
|
@ -1433,16 +1124,18 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst,
|
|||
hdev = inst->core->device;
|
||||
hfi = hdev->hfi_device_data;
|
||||
|
||||
switch (props->prop_data.prop_type) {
|
||||
case CVP_KMD_PROP_HFI_VERSION:
|
||||
{
|
||||
props->prop_data.data = hfi->version;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "unrecognized sys property %d\n",
|
||||
props->prop_data.prop_type);
|
||||
rc = -EFAULT;
|
||||
for (i = 0; i < props->prop_num; i++) {
|
||||
switch (props->prop_data[i].prop_type) {
|
||||
case CVP_KMD_PROP_HFI_VERSION:
|
||||
{
|
||||
props->prop_data[i].data = hfi->version;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "unrecognized sys property %d\n",
|
||||
props->prop_data[i].prop_type);
|
||||
rc = -EFAULT;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1466,7 +1159,7 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst,
|
|||
return -E2BIG;
|
||||
}
|
||||
|
||||
prop_array = &arg->data.sys_properties.prop_data;
|
||||
prop_array = &arg->data.sys_properties.prop_data[0];
|
||||
session_prop = &inst->prop;
|
||||
|
||||
for (i = 0; i < props->prop_num; i++) {
|
||||
|
|
@ -1542,107 +1235,6 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_cancel_input_synx(struct msm_cvp_inst *inst, u32 type, u32 *synx)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
int h_synx;
|
||||
struct synx_session ssid;
|
||||
int start = 0, end = 0;
|
||||
int synx_state = SYNX_STATE_SIGNALED_CANCEL;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
switch (type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
{
|
||||
start = 1;
|
||||
end = HFI_DME_BUF_NUM - 1;
|
||||
break;
|
||||
}
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
{
|
||||
u32 in, out;
|
||||
|
||||
in = synx[0] >> 16;
|
||||
out = synx[0] & 0xFFFF;
|
||||
|
||||
start = 1;
|
||||
end = in + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown fence type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc && rc != -EALREADY) {
|
||||
dprintk(CVP_ERR, "%s: synx_signal %d failed\n",
|
||||
__func__, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_cancel_output_synx(struct msm_cvp_inst *inst, u32 type,
|
||||
u32 *synx)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
int h_synx;
|
||||
struct synx_session ssid;
|
||||
int start = 0, end = 0;
|
||||
int synx_state = SYNX_STATE_SIGNALED_CANCEL;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
switch (type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
{
|
||||
start = FENCE_DME_OUTPUT_IDX;
|
||||
end = FENCE_DME_OUTPUT_IDX + 1;
|
||||
break;
|
||||
}
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
{
|
||||
u32 in, out;
|
||||
|
||||
in = synx[0] >> 16;
|
||||
out = synx[0] & 0xFFFF;
|
||||
|
||||
start = in + 1;
|
||||
end = in + out + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown fence type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: synx_signal %d failed\n",
|
||||
__func__, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_drain_fence_cmd_queue_partial(struct msm_cvp_inst *inst)
|
||||
{
|
||||
unsigned long wait_time;
|
||||
|
|
@ -1783,8 +1375,8 @@ static int cvp_flush_all(struct msm_cvp_inst *inst)
|
|||
|
||||
list_del_init(&f->list);
|
||||
msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata);
|
||||
cvp_cancel_output_synx(inst, f->type, f->synx);
|
||||
cvp_release_synx(inst, f->type, f->synx);
|
||||
cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f);
|
||||
cvp_release_synx(inst, f);
|
||||
cvp_free_fence_data(f);
|
||||
}
|
||||
|
||||
|
|
@ -1795,7 +1387,7 @@ static int cvp_flush_all(struct msm_cvp_inst *inst)
|
|||
__func__, ktid);
|
||||
dprintk(CVP_DBG, "%s: flush frameID %llu from sched_list\n",
|
||||
__func__, f->frame_id);
|
||||
cvp_cancel_input_synx(inst, f->type, f->synx);
|
||||
cvp_cancel_synx(inst, CVP_INPUT_SYNX, f);
|
||||
}
|
||||
|
||||
mutex_unlock(&q->lock);
|
||||
|
|
@ -1899,8 +1491,8 @@ static int cvp_flush_frame(struct msm_cvp_inst *inst, u64 frame_id)
|
|||
|
||||
list_del_init(&f->list);
|
||||
msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata);
|
||||
cvp_cancel_output_synx(inst, f->type, f->synx);
|
||||
cvp_release_synx(inst, f->type, f->synx);
|
||||
cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f);
|
||||
cvp_release_synx(inst, f);
|
||||
cvp_free_fence_data(f);
|
||||
}
|
||||
|
||||
|
|
@ -1914,7 +1506,7 @@ static int cvp_flush_frame(struct msm_cvp_inst *inst, u64 frame_id)
|
|||
__func__, ktid);
|
||||
dprintk(CVP_DBG, "%s: flush frameID %llu from sched_list\n",
|
||||
__func__, f->frame_id);
|
||||
cvp_cancel_input_synx(inst, f->type, f->synx);
|
||||
cvp_cancel_synx(inst, CVP_INPUT_SYNX, f);
|
||||
}
|
||||
|
||||
mutex_unlock(&q->lock);
|
||||
|
|
@ -1962,14 +1554,6 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg)
|
|||
rc = msm_cvp_get_session_info(inst, session);
|
||||
break;
|
||||
}
|
||||
case CVP_KMD_REQUEST_POWER:
|
||||
{
|
||||
struct cvp_kmd_request_power *power =
|
||||
(struct cvp_kmd_request_power *)&arg->data.req_power;
|
||||
|
||||
rc = msm_cvp_request_power(inst, power);
|
||||
break;
|
||||
}
|
||||
case CVP_KMD_UPDATE_POWER:
|
||||
{
|
||||
rc = msm_cvp_update_power(inst);
|
||||
|
|
|
|||
|
|
@ -29,144 +29,7 @@
|
|||
int msm_cvp_est_cycles(struct cvp_kmd_usecase_desc *cvp_desc,
|
||||
struct cvp_kmd_request_power *cvp_voting)
|
||||
{
|
||||
unsigned int cvp_cycles = 0;
|
||||
unsigned int hcd_cycles = 0;
|
||||
unsigned int dme_cycles = 0;
|
||||
unsigned int ds_cycles = 0;
|
||||
unsigned int ncc_cycles = 0;
|
||||
unsigned int num_16x16_blocks = 0;
|
||||
|
||||
unsigned int cvp_bw = 0;
|
||||
unsigned int ds_pixel_read = 0;
|
||||
unsigned int ds_pixel_write = 0;
|
||||
unsigned int hcd_pixel_read = 0;
|
||||
unsigned int hcd_stats_write = 0;
|
||||
unsigned int dme_pixel_read = 0;
|
||||
unsigned int ncc_pixel_read = 0;
|
||||
unsigned int process_width = 0;
|
||||
unsigned int process_height = 0;
|
||||
|
||||
if (!cvp_desc || !cvp_voting) {
|
||||
dprintk(CVP_ERR, "%s: invalid args\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cvp_desc->is_downscale) {
|
||||
num_16x16_blocks = (cvp_desc->fullres_width>>4)
|
||||
* (cvp_desc->fullres_height>>4);
|
||||
ds_cycles = NUM_CYCLES16X16_DS_FRAME * num_16x16_blocks;
|
||||
process_width = cvp_desc->downscale_width;
|
||||
process_height = cvp_desc->downscale_height;
|
||||
num_16x16_blocks = (process_width>>4)*(process_height>>4);
|
||||
hcd_cycles = NUM_CYCLES16X16_HCD_FRAME * num_16x16_blocks;
|
||||
/*Estimate downscale output (always UBWC) BW stats*/
|
||||
if (cvp_desc->fullres_width <= 1920) {
|
||||
/*w*h/1.58=w*h*(81/128)*/
|
||||
ds_pixel_write = ((process_width*process_height*81)>>7);
|
||||
} else {
|
||||
/*w*h/2.38=w*h*(54/128)*/
|
||||
ds_pixel_write = ((process_width*process_height*54)>>7);
|
||||
}
|
||||
/*Estimate downscale input BW stats based on colorfmt*/
|
||||
switch (cvp_desc->colorfmt) {
|
||||
case COLOR_FMT_NV12:
|
||||
{
|
||||
/*w*h*1.5*/
|
||||
ds_pixel_read = ((cvp_desc->fullres_width
|
||||
* cvp_desc->fullres_height * 3)>>1);
|
||||
break;
|
||||
}
|
||||
case COLOR_FMT_P010:
|
||||
{
|
||||
/*w*h*2*1.5*/
|
||||
ds_pixel_read = cvp_desc->fullres_width
|
||||
* cvp_desc->fullres_height * 3;
|
||||
break;
|
||||
}
|
||||
case COLOR_FMT_NV12_UBWC:
|
||||
{
|
||||
/*w*h*1.5/factor(factor=width>1920?2.38:1.58)*/
|
||||
if (cvp_desc->fullres_width <= 1920) {
|
||||
/*w*h*1.5/1.58 = w*h*121/128*/
|
||||
ds_pixel_read = ((cvp_desc->fullres_width
|
||||
* cvp_desc->fullres_height * 121)>>7);
|
||||
} else {
|
||||
/*w*h*1.5/1.61 = w*h*119/128*/
|
||||
ds_pixel_read = ((cvp_desc->fullres_width
|
||||
* cvp_desc->fullres_height * 119)>>7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COLOR_FMT_NV12_BPP10_UBWC:
|
||||
{
|
||||
/*w*h*1.33*1.5/factor(factor=width>1920?2.38:1.58)*/
|
||||
if (cvp_desc->fullres_width <= 1920) {
|
||||
/*w*h*1.33*1.5/1.58 = w*h*5/4*/
|
||||
ds_pixel_read = ((cvp_desc->fullres_width
|
||||
* cvp_desc->fullres_height * 5)>>2);
|
||||
} else {
|
||||
/*w*h*1.33*1.5/1.61 = w*h*79/64*/
|
||||
ds_pixel_read = ((cvp_desc->fullres_width
|
||||
* cvp_desc->fullres_height * 79)>>6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "Defaulting to linear P010\n");
|
||||
/*w*h*1.5*2 COLOR_FMT_P010*/
|
||||
ds_pixel_read = (cvp_desc->fullres_width
|
||||
* cvp_desc->fullres_height * 3);
|
||||
}
|
||||
} else {
|
||||
process_width = cvp_desc->fullres_width;
|
||||
process_height = cvp_desc->fullres_height;
|
||||
num_16x16_blocks = (process_width>>4)*(process_height>>4);
|
||||
hcd_cycles = NUM_CYCLES16X16_HCD_FRAME * num_16x16_blocks;
|
||||
}
|
||||
|
||||
dme_cycles = NUM_CYCLES16X16_DME_FRAME * NUM_DME_MAX_FEATURE_POINTS;
|
||||
ncc_cycles = NUM_CYCLES16X16_NCC_FRAME * NUM_DME_MAX_FEATURE_POINTS;
|
||||
|
||||
cvp_cycles = dme_cycles + ds_cycles + hcd_cycles + ncc_cycles;
|
||||
cvp_cycles = cvp_cycles + (cvp_cycles>>CYCLES_MARGIN_IN_POWEROF2);
|
||||
|
||||
cvp_voting->clock_cycles_a = cvp_cycles * cvp_desc->fps;
|
||||
cvp_voting->clock_cycles_b = 0;
|
||||
cvp_voting->reserved[0] = NUM_CYCLESFW_FRAME * cvp_desc->fps;
|
||||
cvp_voting->reserved[1] = cvp_cycles * cvp_desc->op_rate;
|
||||
cvp_voting->reserved[2] = 0;
|
||||
cvp_voting->reserved[3] = NUM_CYCLESFW_FRAME*cvp_desc->op_rate;
|
||||
|
||||
if (process_width <= 1920) {
|
||||
/*w*h*1.5(for filter fetch overhead)/1.58=w*h*(3/2)*(5/8)*/
|
||||
hcd_pixel_read = ((process_width * process_height * 15)>>4);
|
||||
/*num_16x16_blocks*8*4*/
|
||||
hcd_stats_write = (num_16x16_blocks<<5);
|
||||
/*NUM_DME_MAX_FEATURE_POINTS*96*48/1.58*/
|
||||
dme_pixel_read = NUM_DME_MAX_FEATURE_POINTS * 2880;
|
||||
/*NUM_DME_MAX_FEATURE_POINTS*(18/8+1)*32*8*2/1.58*/
|
||||
ncc_pixel_read = NUM_DME_MAX_FEATURE_POINTS * 1040;
|
||||
} else {
|
||||
/*w*h*1.5(for filter fetch overhead)/2.38=w*h*(3/2)*(54/128)*/
|
||||
hcd_pixel_read = ((process_width * process_height * 81)>>7);
|
||||
/*num_16x16_blocks*8*4*/
|
||||
hcd_stats_write = (num_16x16_blocks<<5);
|
||||
/*NUM_DME_MAX_FEATURE_POINTS*96*48/2.38*/
|
||||
dme_pixel_read = NUM_DME_MAX_FEATURE_POINTS * 1944;
|
||||
/*NUM_DME_MAX_FEATURE_POINTS*(18/8+1)*32*8*2/2.38*/
|
||||
ncc_pixel_read = NUM_DME_MAX_FEATURE_POINTS * 702;
|
||||
}
|
||||
|
||||
cvp_bw = ds_pixel_read + ds_pixel_write + hcd_pixel_read
|
||||
+ hcd_stats_write + dme_pixel_read + ncc_pixel_read;
|
||||
|
||||
cvp_voting->ddr_bw = cvp_bw * cvp_desc->fps;
|
||||
cvp_voting->reserved[4] = cvp_bw * cvp_desc->op_rate;
|
||||
|
||||
dprintk(CVP_DBG, "%s Voting cycles_a, b, bw: %d %d %d\n", __func__,
|
||||
cvp_voting->clock_cycles_a, cvp_voting->clock_cycles_b,
|
||||
cvp_voting->ddr_bw);
|
||||
|
||||
dprintk(CVP_ERR, "Deprecated cvp func %s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(msm_cvp_est_cycles);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <media/msm_cvp_private.h>
|
||||
#include <media/msm_cvp_vidc.h>
|
||||
#include "msm_cvp_buf.h"
|
||||
#include "msm_cvp_synx.h"
|
||||
|
||||
enum core_id {
|
||||
MSM_CORE_CVP = 0,
|
||||
|
|
|
|||
|
|
@ -194,13 +194,6 @@ struct cvp_session_msg {
|
|||
struct cvp_hfi_msg_session_hdr pkt;
|
||||
};
|
||||
|
||||
enum queue_state {
|
||||
QUEUE_INIT,
|
||||
QUEUE_ACTIVE = 1,
|
||||
QUEUE_STOP = 2,
|
||||
QUEUE_INVALID,
|
||||
};
|
||||
|
||||
struct cvp_session_queue {
|
||||
spinlock_t lock;
|
||||
enum queue_state state;
|
||||
|
|
@ -232,22 +225,6 @@ struct cvp_session_prop {
|
|||
u32 ddr_op_cache;
|
||||
};
|
||||
|
||||
enum op_mode {
|
||||
OP_NORMAL,
|
||||
OP_DRAINING,
|
||||
OP_FLUSH,
|
||||
OP_INVALID,
|
||||
};
|
||||
|
||||
struct cvp_fence_queue {
|
||||
struct mutex lock;
|
||||
enum queue_state state;
|
||||
enum op_mode mode;
|
||||
struct list_head wait_list;
|
||||
wait_queue_head_t wq;
|
||||
struct list_head sched_list;
|
||||
};
|
||||
|
||||
enum cvp_event_t {
|
||||
CVP_NO_EVENT,
|
||||
CVP_SSR_EVENT = 1,
|
||||
|
|
@ -312,27 +289,12 @@ struct msm_cvp_inst {
|
|||
enum msm_cvp_modes flags;
|
||||
struct msm_cvp_capability capability;
|
||||
struct kref kref;
|
||||
struct cvp_kmd_request_power power;
|
||||
struct cvp_session_prop prop;
|
||||
u32 cur_cmd_type;
|
||||
struct synx_session synx_session_id;
|
||||
struct cvp_fence_queue fence_cmd_queue;
|
||||
};
|
||||
|
||||
struct cvp_fence_type {
|
||||
s32 h_synx;
|
||||
u32 secure_key;
|
||||
};
|
||||
|
||||
struct cvp_fence_command {
|
||||
struct list_head list;
|
||||
u64 frame_id;
|
||||
enum op_mode mode;
|
||||
u32 type;
|
||||
u32 synx[MAX_HFI_FENCE_SIZE/2];
|
||||
struct cvp_hfi_cmd_session_hdr *pkt;
|
||||
};
|
||||
|
||||
extern struct msm_cvp_drv *cvp_driver;
|
||||
|
||||
void cvp_handle_cmd_response(enum hal_command_response cmd, void *data);
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ set_default_pkt_hdr:
|
|||
static int _get_fence_pkt_hdr_from_user(struct cvp_kmd_arg __user *up,
|
||||
struct cvp_hal_session_cmd_pkt *pkt_hdr)
|
||||
{
|
||||
struct cvp_kmd_hfi_fence_packet *u;
|
||||
struct cvp_kmd_hfi_synx_packet __user *u;
|
||||
|
||||
u = &up->data.hfi_fence_pkt;
|
||||
u = &up->data.hfi_synx_pkt;
|
||||
|
||||
if (get_user(pkt_hdr->size, &u->pkt_data[0]))
|
||||
return -EFAULT;
|
||||
|
|
@ -73,21 +73,27 @@ static int _copy_pkt_from_user(struct cvp_kmd_arg *kp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Size is in unit of u32 */
|
||||
static int _copy_fence_pkt_from_user(struct cvp_kmd_arg *kp,
|
||||
struct cvp_kmd_arg __user *up,
|
||||
unsigned int size)
|
||||
static int _copy_synx_data_from_user(
|
||||
struct cvp_kmd_hfi_synx_packet *k,
|
||||
struct cvp_kmd_hfi_synx_packet __user *u)
|
||||
{
|
||||
struct cvp_kmd_hfi_fence_packet *k;
|
||||
struct cvp_kmd_hfi_fence_packet __user *u;
|
||||
int i;
|
||||
|
||||
k = &kp->data.hfi_fence_pkt;
|
||||
u = &up->data.hfi_fence_pkt;
|
||||
for (i = 0; i < MAX_HFI_FENCE_OFFSET; i++) {
|
||||
if (get_user(k->pkt_data[i], &u->pkt_data[i]))
|
||||
for (i = 0; i < MAX_FENCE_DATA_SIZE; i++) {
|
||||
if (get_user(k->fence_data[i], &u->fence_data[i]))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Size is in unit of u32 */
|
||||
static int _copy_fence_data_from_user_deprecate(
|
||||
struct cvp_kmd_hfi_fence_packet *k,
|
||||
struct cvp_kmd_hfi_fence_packet __user *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_HFI_FENCE_SIZE; i++) {
|
||||
if (get_user(k->fence_data[i], &u->fence_data[i]))
|
||||
return -EFAULT;
|
||||
|
|
@ -98,10 +104,34 @@ static int _copy_fence_pkt_from_user(struct cvp_kmd_arg *kp,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _copy_fence_pkt_from_user(struct cvp_kmd_arg *kp,
|
||||
struct cvp_kmd_arg __user *up)
|
||||
{ struct cvp_kmd_hfi_synx_packet *k;
|
||||
struct cvp_kmd_hfi_synx_packet __user *u;
|
||||
struct cvp_kmd_hfi_fence_packet __user *u1;
|
||||
int i;
|
||||
|
||||
k = &kp->data.hfi_synx_pkt;
|
||||
u = &up->data.hfi_synx_pkt;
|
||||
u1 = &up->data.hfi_fence_pkt;
|
||||
|
||||
for (i = 0; i < MAX_HFI_PKT_SIZE; i++)
|
||||
if (get_user(k->pkt_data[i], &u->pkt_data[i]))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(k->fence_data[0], &u->fence_data[0]))
|
||||
return -EFAULT;
|
||||
|
||||
if (k->fence_data[0] == 0xFEEDFACE)
|
||||
return _copy_synx_data_from_user(k, u);
|
||||
else
|
||||
return _copy_fence_data_from_user_deprecate(
|
||||
(struct cvp_kmd_hfi_fence_packet *)k, u1);
|
||||
}
|
||||
|
||||
static int _copy_frameid_from_user(struct cvp_kmd_arg *kp,
|
||||
struct cvp_kmd_arg __user *up)
|
||||
{
|
||||
|
|
@ -150,35 +180,35 @@ static int _copy_pkt_to_user(struct cvp_kmd_arg *kp,
|
|||
}
|
||||
|
||||
static int _copy_fence_pkt_to_user(struct cvp_kmd_arg *kp,
|
||||
struct cvp_kmd_arg __user *up,
|
||||
unsigned int size)
|
||||
struct cvp_kmd_arg __user *up)
|
||||
{
|
||||
struct cvp_kmd_hfi_fence_packet *k, *u;
|
||||
struct cvp_kmd_hfi_synx_packet *k;
|
||||
struct cvp_kmd_hfi_synx_packet __user *u;
|
||||
int i;
|
||||
|
||||
k = &kp->data.hfi_fence_pkt;
|
||||
u = &up->data.hfi_fence_pkt;
|
||||
for (i = 0; i < MAX_HFI_FENCE_OFFSET; i++) {
|
||||
k = &kp->data.hfi_synx_pkt;
|
||||
u = &up->data.hfi_synx_pkt;
|
||||
for (i = 0; i < MAX_HFI_PKT_SIZE; i++) {
|
||||
if (put_user(k->pkt_data[i], &u->pkt_data[i]))
|
||||
return -EFAULT;
|
||||
}
|
||||
for (i = 0; i < MAX_HFI_FENCE_SIZE; i++) {
|
||||
if (put_user(k->fence_data[i], &u->fence_data[i]))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _copy_sysprop_to_user(struct cvp_kmd_arg *kp,
|
||||
struct cvp_kmd_arg __user *up)
|
||||
{
|
||||
struct cvp_kmd_sys_properties *k, *u;
|
||||
struct cvp_kmd_sys_properties *k;
|
||||
struct cvp_kmd_sys_properties __user *u;
|
||||
int i;
|
||||
|
||||
k = &kp->data.sys_properties;
|
||||
u = &up->data.sys_properties;
|
||||
|
||||
if (put_user(k->prop_data.data, &u->prop_data.data))
|
||||
return -EFAULT;
|
||||
for (i = 0; i < 8; i++)
|
||||
if (put_user(k->prop_data[i].data, &u->prop_data[i].data))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -245,26 +275,6 @@ static int _get_session_info_from_user(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _get_power_request(
|
||||
struct cvp_kmd_request_power *k,
|
||||
struct cvp_kmd_request_power __user *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (get_user(k->clock_cycles_a, &u->clock_cycles_a) ||
|
||||
get_user(k->clock_cycles_b, &u->clock_cycles_b) ||
|
||||
get_user(k->ddr_bw, &u->ddr_bw) ||
|
||||
get_user(k->sys_cache_bw, &u->sys_cache_bw))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (get_user(k->reserved[i], &u->reserved[i]))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int convert_from_user(struct cvp_kmd_arg *kp,
|
||||
unsigned long arg,
|
||||
struct msm_cvp_inst *inst)
|
||||
|
|
@ -304,20 +314,6 @@ static int convert_from_user(struct cvp_kmd_arg *kp,
|
|||
|
||||
break;
|
||||
}
|
||||
case CVP_KMD_REQUEST_POWER:
|
||||
{
|
||||
struct cvp_kmd_request_power *k;
|
||||
struct cvp_kmd_request_power __user *u;
|
||||
|
||||
k = &kp->data.req_power;
|
||||
u = &up->data.req_power;
|
||||
if (_get_power_request(k, u)) {
|
||||
dprintk(CVP_ERR, "fail to get power request\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CVP_KMD_REGISTER_BUFFER:
|
||||
{
|
||||
struct cvp_kmd_buffer *k, *u;
|
||||
|
|
@ -386,7 +382,7 @@ static int convert_from_user(struct cvp_kmd_arg *kp,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
rc = _copy_fence_pkt_from_user(kp, up, (pkt_hdr.size >> 2));
|
||||
rc = _copy_fence_pkt_from_user(kp, up);
|
||||
break;
|
||||
}
|
||||
case CVP_KMD_RECEIVE_MSG_PKT:
|
||||
|
|
@ -452,26 +448,6 @@ static int _put_user_session_info(
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _put_power_request(
|
||||
struct cvp_kmd_request_power *k,
|
||||
struct cvp_kmd_request_power __user *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (put_user(k->clock_cycles_a, &u->clock_cycles_a) ||
|
||||
put_user(k->clock_cycles_b, &u->clock_cycles_b) ||
|
||||
put_user(k->ddr_bw, &u->ddr_bw) ||
|
||||
put_user(k->sys_cache_bw, &u->sys_cache_bw))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (put_user(k->reserved[i], &u->reserved[i]))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -513,20 +489,6 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg)
|
|||
|
||||
break;
|
||||
}
|
||||
case CVP_KMD_REQUEST_POWER:
|
||||
{
|
||||
struct cvp_kmd_request_power *k;
|
||||
struct cvp_kmd_request_power __user *u;
|
||||
|
||||
k = &kp->data.req_power;
|
||||
u = &up->data.req_power;
|
||||
if (_put_power_request(k, u)) {
|
||||
dprintk(CVP_ERR, "fail to copy power to user\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CVP_KMD_REGISTER_BUFFER:
|
||||
{
|
||||
struct cvp_kmd_buffer *k, *u;
|
||||
|
|
@ -583,7 +545,7 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg)
|
|||
dprintk(CVP_DBG, "Send user cmd pkt: %d %d\n",
|
||||
pkt_hdr.size, pkt_hdr.packet_type);
|
||||
|
||||
rc = _copy_fence_pkt_to_user(kp, up, (pkt_hdr.size >> 2));
|
||||
rc = _copy_fence_pkt_to_user(kp, up);
|
||||
break;
|
||||
}
|
||||
case CVP_KMD_SESSION_CONTROL:
|
||||
|
|
|
|||
565
drivers/media/platform/msm/cvp/msm_cvp_synx.c
Normal file
565
drivers/media/platform/msm/cvp/msm_cvp_synx.c
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, 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"
|
||||
|
||||
static int cvp_import_synx_deprecate(struct msm_cvp_inst *inst, u32 type,
|
||||
u32 *fence, u32 *synx)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
int start = 0, end = 0;
|
||||
struct cvp_fence_type *f;
|
||||
struct synx_import_params params;
|
||||
s32 h_synx;
|
||||
struct synx_session ssid;
|
||||
|
||||
f = (struct cvp_fence_type *)fence;
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
switch (type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
{
|
||||
start = 0;
|
||||
end = HFI_DME_BUF_NUM;
|
||||
break;
|
||||
}
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
{
|
||||
u32 in = fence[0];
|
||||
u32 out = fence[1];
|
||||
|
||||
if (in > MAX_HFI_FENCE_SIZE || out > MAX_HFI_FENCE_SIZE
|
||||
|| in > MAX_HFI_FENCE_SIZE - out) {
|
||||
dprintk(CVP_ERR, "%s: failed!\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
synx[0] = (in << 16) | out;
|
||||
start = 1;
|
||||
end = in + out + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown fence type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = f[i].h_synx;
|
||||
|
||||
if (h_synx) {
|
||||
params.h_synx = h_synx;
|
||||
params.secure_key = f[i].secure_key;
|
||||
params.new_h_synx = &synx[i];
|
||||
|
||||
rc = synx_import(ssid, ¶ms);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_import failed\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc,
|
||||
u32 *fence)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
struct cvp_fence_type *fs;
|
||||
struct synx_import_params params;
|
||||
s32 h_synx;
|
||||
struct synx_session ssid;
|
||||
|
||||
if (fc->signature != 0xFEEDFACE)
|
||||
return cvp_import_synx_deprecate(inst, fc->type, fence,
|
||||
fc->synx);
|
||||
|
||||
fs = (struct cvp_fence_type *)fence;
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
for (i = 0; i < fc->num_fences; ++i) {
|
||||
h_synx = fs[i].h_synx;
|
||||
|
||||
if (h_synx) {
|
||||
params.h_synx = h_synx;
|
||||
params.secure_key = fs[i].secure_key;
|
||||
params.new_h_synx = &fc->synx[i];
|
||||
|
||||
rc = synx_import(ssid, ¶ms);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_import failed\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_release_synx_deprecate(struct msm_cvp_inst *inst, u32 type,
|
||||
u32 *synx)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
s32 h_synx;
|
||||
struct synx_session ssid;
|
||||
int start = 0, end = 0;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
switch (type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
{
|
||||
start = 0;
|
||||
end = HFI_DME_BUF_NUM;
|
||||
|
||||
break;
|
||||
}
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
{
|
||||
u32 in = synx[0] >> 16;
|
||||
u32 out = synx[0] & 0xFFFF;
|
||||
|
||||
start = 1;
|
||||
end = in + out + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown fence type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_release(ssid, h_synx);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_release %d failed\n",
|
||||
__func__, i);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
s32 h_synx;
|
||||
struct synx_session ssid;
|
||||
|
||||
if (fc->signature != 0xFEEDFACE)
|
||||
return cvp_release_synx_deprecate(inst, fc->type, fc->synx);
|
||||
|
||||
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 failed\n",
|
||||
__func__, i);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_cancel_input_synx_deprecate(struct msm_cvp_inst *inst, u32 type,
|
||||
u32 *synx)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
int h_synx;
|
||||
struct synx_session ssid;
|
||||
int start = 0, end = 0;
|
||||
int synx_state = SYNX_STATE_SIGNALED_CANCEL;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
switch (type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
{
|
||||
start = 1;
|
||||
end = HFI_DME_BUF_NUM - 1;
|
||||
break;
|
||||
}
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
{
|
||||
u32 in, out;
|
||||
|
||||
in = synx[0] >> 16;
|
||||
out = synx[0] & 0xFFFF;
|
||||
|
||||
start = 1;
|
||||
end = in + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown fence type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc && rc != -EALREADY) {
|
||||
dprintk(CVP_ERR, "%s: synx_signal %d failed\n",
|
||||
__func__, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_cancel_output_synx_deprecate(struct msm_cvp_inst *inst, u32 type,
|
||||
u32 *synx)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
int h_synx;
|
||||
struct synx_session ssid;
|
||||
int start = 0, end = 0;
|
||||
int synx_state = SYNX_STATE_SIGNALED_CANCEL;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
switch (type) {
|
||||
case HFI_CMD_SESSION_CVP_DME_FRAME:
|
||||
{
|
||||
start = FENCE_DME_OUTPUT_IDX;
|
||||
end = FENCE_DME_OUTPUT_IDX + 1;
|
||||
break;
|
||||
}
|
||||
case HFI_CMD_SESSION_CVP_FD_FRAME:
|
||||
{
|
||||
u32 in, out;
|
||||
|
||||
in = synx[0] >> 16;
|
||||
out = synx[0] & 0xFFFF;
|
||||
|
||||
start = in + 1;
|
||||
end = in + out + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown fence type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: synx_signal %d failed\n",
|
||||
__func__, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst,
|
||||
enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
int h_synx;
|
||||
struct synx_session ssid;
|
||||
int start = 0, end = 0;
|
||||
int synx_state = SYNX_STATE_SIGNALED_CANCEL;
|
||||
|
||||
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);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: synx_signal %d failed\n",
|
||||
__func__, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc)
|
||||
{
|
||||
if (fc->signature != 0xFEEDFACE) {
|
||||
if (type == CVP_INPUT_SYNX)
|
||||
return cvp_cancel_input_synx_deprecate(inst, fc->type,
|
||||
fc->synx);
|
||||
else if (type == CVP_OUTPUT_SYNX)
|
||||
return cvp_cancel_output_synx_deprecate(inst, fc->type,
|
||||
fc->synx);
|
||||
else {
|
||||
dprintk(CVP_ERR, "Incorrect synx type %d\n", type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return cvp_cancel_synx_impl(inst, type, fc);
|
||||
}
|
||||
|
||||
static int cvp_wait_dme_synx_deprecate(struct synx_session ssid, u32 *synx,
|
||||
u32 *synx_state)
|
||||
{
|
||||
int i, rc = 0;
|
||||
int h_synx;
|
||||
unsigned long timeout_ms = 1000;
|
||||
|
||||
i = 0;
|
||||
while (i < HFI_DME_BUF_NUM - 1) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_wait(ssid, h_synx, timeout_ms);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s %s: synx_wait %d failed\n",
|
||||
current->comm, __func__, i);
|
||||
*synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
* Increase loop count to skip fence
|
||||
* waiting on downscale image where i == 1.
|
||||
*/
|
||||
if (i == FENCE_DME_ICA_ENABLED_IDX)
|
||||
++i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_signal_dme_synx_deprecate(struct synx_session ssid, u32 *synx,
|
||||
u32 synx_state)
|
||||
{
|
||||
int rc = 0;
|
||||
int h_synx;
|
||||
|
||||
if (synx[FENCE_DME_ICA_ENABLED_IDX]) {
|
||||
h_synx = synx[FENCE_DME_DS_IDX];
|
||||
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s %s: synx_signal %d failed\n",
|
||||
current->comm, __func__, FENCE_DME_DS_IDX);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
h_synx = synx[FENCE_DME_OUTPUT_IDX];
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR, "%s %s: synx_signal %d failed\n",
|
||||
current->comm, __func__, FENCE_DME_OUTPUT_IDX);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_wait_fd_synx_deprecate(struct synx_session ssid, u32 *synx,
|
||||
u32 *synx_state)
|
||||
{
|
||||
int i, rc = 0;
|
||||
unsigned long timeout_ms = 1000;
|
||||
int h_synx;
|
||||
u32 in;
|
||||
|
||||
in = synx[0] >> 16;
|
||||
|
||||
i = 1;
|
||||
while (i <= in) {
|
||||
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_CANCEL) {
|
||||
dprintk(CVP_DBG,
|
||||
"%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_ERROR;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_signal_fd_synx_deprecate(struct synx_session ssid, u32 *synx,
|
||||
u32 synx_state)
|
||||
{
|
||||
int i, rc = 0;
|
||||
u32 in, out;
|
||||
int h_synx;
|
||||
|
||||
in = synx[0] >> 16;
|
||||
out = synx[0] & 0xFFFF;
|
||||
|
||||
i = in + 1;
|
||||
while (i <= in + out) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: synx_signal %d failed\n",
|
||||
current->comm, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
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 = 1000;
|
||||
int 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_CANCEL) {
|
||||
dprintk(CVP_DBG,
|
||||
"%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_ERROR;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
++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;
|
||||
int 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 %d failed\n",
|
||||
current->comm, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_ERROR;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc, u32 *synx_state)
|
||||
{
|
||||
struct synx_session ssid;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
if (fc->signature != 0xFEEDFACE) {
|
||||
if (fc->type == HFI_CMD_SESSION_CVP_DME_FRAME) {
|
||||
if (type == CVP_INPUT_SYNX)
|
||||
return cvp_wait_dme_synx_deprecate(ssid,
|
||||
fc->synx, synx_state);
|
||||
else if (type == CVP_OUTPUT_SYNX)
|
||||
return cvp_signal_dme_synx_deprecate(ssid,
|
||||
fc->synx, *synx_state);
|
||||
else
|
||||
return -EINVAL;
|
||||
} else if (fc->type == HFI_CMD_SESSION_CVP_FD_FRAME) {
|
||||
if (type == CVP_INPUT_SYNX)
|
||||
return cvp_wait_fd_synx_deprecate(ssid,
|
||||
fc->synx, synx_state);
|
||||
else if (type == CVP_OUTPUT_SYNX)
|
||||
return cvp_signal_fd_synx_deprecate(ssid,
|
||||
fc->synx, *synx_state);
|
||||
else
|
||||
return -EINVAL;
|
||||
} else {
|
||||
dprintk(CVP_ERR, "%s Incorrect pkt type\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
54
drivers/media/platform/msm/cvp/msm_cvp_synx.h
Normal file
54
drivers/media/platform/msm/cvp/msm_cvp_synx.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_CVP_SYNX_H_
|
||||
#define _MSM_CVP_SYNX_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <media/msm_cvp_private.h>
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
|
||||
struct cvp_fence_queue {
|
||||
struct mutex lock;
|
||||
enum queue_state state;
|
||||
enum op_mode mode;
|
||||
struct list_head wait_list;
|
||||
wait_queue_head_t wq;
|
||||
struct list_head sched_list;
|
||||
};
|
||||
|
||||
struct cvp_fence_type {
|
||||
s32 h_synx;
|
||||
u32 secure_key;
|
||||
};
|
||||
|
||||
struct cvp_fence_command {
|
||||
struct list_head list;
|
||||
u64 frame_id;
|
||||
enum op_mode mode;
|
||||
u32 signature;
|
||||
u32 num_fences;
|
||||
u32 output_index;
|
||||
u32 type;
|
||||
u32 synx[MAX_HFI_FENCE_SIZE/2];
|
||||
struct cvp_hfi_cmd_session_hdr *pkt;
|
||||
};
|
||||
|
||||
enum cvp_synx_type {
|
||||
CVP_UINIT_SYNX,
|
||||
CVP_INPUT_SYNX,
|
||||
CVP_OUTPUT_SYNX,
|
||||
CVP_INVALID_SYNX,
|
||||
};
|
||||
|
||||
int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc,
|
||||
u32 *fence);
|
||||
int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc);
|
||||
int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc);
|
||||
int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc, u32 *synx_state);
|
||||
#endif
|
||||
|
|
@ -23,13 +23,6 @@
|
|||
*/
|
||||
#define CVP_KMD_GET_SESSION_INFO (CVP_KMD_CMD_START + 1)
|
||||
|
||||
/*
|
||||
* CVP_KMD_REQUEST_POWER - this argument type is used to
|
||||
* set the power required to driver. it passes
|
||||
* struct cvp_kmd_request_power {}
|
||||
*/
|
||||
#define CVP_KMD_REQUEST_POWER (CVP_KMD_CMD_START + 2)
|
||||
|
||||
/*
|
||||
* CVP_KMD_REGISTER_BUFFER - this argument type is used to
|
||||
* register the buffer to driver. it passes
|
||||
|
|
@ -82,21 +75,6 @@ struct cvp_kmd_session_info {
|
|||
__u32 reserved[10];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cvp_kmd_request_power - power / clock data information
|
||||
* @clock_cycles_a: clock cycles per second required for hardware_a
|
||||
* @clock_cycles_b: clock cycles per second required for hardware_b
|
||||
* @ddr_bw: bandwidth required for ddr in bps
|
||||
* @sys_cache_bw: bandwidth required for system cache in bps
|
||||
*/
|
||||
struct cvp_kmd_request_power {
|
||||
__u32 clock_cycles_a;
|
||||
__u32 clock_cycles_b;
|
||||
__u32 ddr_bw;
|
||||
__u32 sys_cache_bw;
|
||||
__u32 reserved[8];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cvp_kmd_buffer - buffer information to be registered
|
||||
* @index: index of buffer
|
||||
|
|
@ -180,7 +158,7 @@ struct cvp_kmd_sys_property {
|
|||
|
||||
struct cvp_kmd_sys_properties {
|
||||
__u32 prop_num;
|
||||
struct cvp_kmd_sys_property prop_data;
|
||||
struct cvp_kmd_sys_property prop_data[8];
|
||||
};
|
||||
|
||||
#define SESSION_CREATE 1
|
||||
|
|
@ -202,6 +180,29 @@ struct cvp_kmd_hfi_fence_packet {
|
|||
__u64 frame_id;
|
||||
};
|
||||
|
||||
struct cvp_kmd_fence {
|
||||
__s32 h_synx;
|
||||
__u32 secure_key;
|
||||
};
|
||||
|
||||
struct cvp_kmd_fence_ctrl {
|
||||
__u32 magic;
|
||||
__u32 reserved;
|
||||
__u64 frame_id;
|
||||
__u32 num_fences;
|
||||
__u32 output_index;
|
||||
struct cvp_kmd_fence fences[MAX_HFI_FENCE_SIZE/2];
|
||||
};
|
||||
|
||||
#define MAX_FENCE_DATA_SIZE (MAX_HFI_FENCE_SIZE + 6)
|
||||
|
||||
struct cvp_kmd_hfi_synx_packet {
|
||||
__u32 pkt_data[MAX_HFI_PKT_SIZE];
|
||||
union {
|
||||
__u32 fence_data[MAX_FENCE_DATA_SIZE];
|
||||
struct cvp_kmd_fence_ctrl fc;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cvp_kmd_arg
|
||||
|
|
@ -225,15 +226,19 @@ struct cvp_kmd_arg {
|
|||
__u32 buf_num;
|
||||
union cvp_data_t {
|
||||
struct cvp_kmd_session_info session;
|
||||
struct cvp_kmd_request_power req_power;
|
||||
struct cvp_kmd_buffer regbuf;
|
||||
struct cvp_kmd_buffer unregbuf;
|
||||
struct cvp_kmd_send_cmd send_cmd;
|
||||
struct cvp_kmd_hfi_packet hfi_pkt;
|
||||
struct cvp_kmd_sys_properties sys_properties;
|
||||
struct cvp_kmd_hfi_fence_packet hfi_fence_pkt;
|
||||
struct cvp_kmd_hfi_synx_packet hfi_synx_pkt;
|
||||
struct cvp_kmd_session_control session_ctrl;
|
||||
__u64 frame_id;
|
||||
} data;
|
||||
};
|
||||
|
||||
struct cvp_kmd_request_power {
|
||||
__u32 deprecated;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue