Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7aca1d1a authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: cvp: Enable CVP down-scaling feature"

parents 2fdd6eff 0640d4af
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -80,7 +80,13 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = {
		.buf_num = HFI_PERSIST_BUF_NUM,
		.resp = HAL_NO_RESP,
	},

	{
		.size = HFI_DS_CMD_SIZE,
		.type = HFI_CMD_SESSION_CVP_DS,
		.buf_offset = HFI_DS_BUFFERS_OFFSET,
		.buf_num = HFI_DS_BUF_NUM,
		.resp = HAL_NO_RESP,
	},
};

static struct hal_device_data hal_ctxt;
@@ -118,7 +124,7 @@ const struct msm_cvp_gov_data CVP_DEFAULT_BUS_VOTE = {
	.data_count = 0,
};

const int cvp_max_packets = 1000;
const int cvp_max_packets = 32;

static void venus_hfi_pm_handler(struct work_struct *work);
static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler);
@@ -3268,6 +3274,9 @@ static int __response_handler(struct venus_hfi_device *device)
					"Corrupt/unknown packet found, discarding\n");
			--packet_count;
			continue;
		} else if (info->response_type == HAL_NO_RESP) {
			--packet_count;
			continue;
		}

		/* Process the packet types that we're interested in */
+5 −0
Original line number Diff line number Diff line
@@ -72,6 +72,10 @@
#define HFI_PERSIST_BUFFERS_OFFSET 7
#define HFI_PERSIST_BUF_NUM     2

#define HFI_DS_CMD_SIZE	54
#define HFI_DS_BUFFERS_OFFSET	48
#define HFI_DS_BUF_NUM	3


enum cvp_status {
	CVP_ERR_NONE = 0x0,
@@ -1270,6 +1274,7 @@ struct msm_cvp_cb_cmd_done {
	enum cvp_status status;
	u32 size;
	union {
		struct hfi_msg_session_hdr msg_hdr;
		struct cvp_resource_hdr resource_hdr;
		struct cvp_buffer_addr_info buffer_addr_info;
		struct cvp_frame_plane_config frame_plane_config;
+1 −1
Original line number Diff line number Diff line
@@ -1020,7 +1020,7 @@ struct hfi_cmd_session_cvp_release_buffers_packet {
	u32 buffer_idx;
};

struct hfi_msg_session_cvp_release_buffers_done_packet {
struct hfi_msg_session_hdr {
	u32 size;
	u32 packet_type;
	u32 session_id;
+89 −15
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
#include "cvp_hfi_io.h"
#include "msm_cvp_debug.h"
#include "cvp_hfi.h"
#include "msm_cvp_common.h"

extern struct msm_cvp_drv *cvp_driver;

static enum cvp_status hfi_map_err_status(u32 hfi_err)
{
@@ -823,12 +826,12 @@ static int hfi_process_session_set_buf_done(u32 device_id,


static int hfi_process_session_rel_buf_done(u32 device_id,
		struct hfi_msg_session_cvp_release_buffers_done_packet *pkt,
		struct hfi_msg_session_hdr *pkt,
		struct msm_cvp_cb_info *info)
{
	struct msm_cvp_cb_cmd_done cmd_done = {0};
	unsigned int pkt_size =
		sizeof(struct hfi_msg_session_cvp_release_buffers_done_packet);
		sizeof(struct hfi_msg_session_hdr);

	if (!pkt || pkt->size < pkt_size) {
		dprintk(CVP_ERR, "bad packet/packet size %d\n",
@@ -921,6 +924,84 @@ static int hfi_process_session_cvp_dfs(u32 device_id,
	return 0;
}

static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core,
	void *session_id)
{
	struct msm_cvp_inst *inst = NULL;
	bool match = false;

	if (!core || !session_id)
		return NULL;

	mutex_lock(&core->lock);
	list_for_each_entry(inst, &core->instances, list) {
		if (hash32_ptr(inst->session) == (unsigned int)session_id) {
			match = true;
			break;
		}
	}

	inst = match ? inst : NULL;
	mutex_unlock(&core->lock);

	return inst;

}

static int hfi_process_session_cvp_msg(u32 device_id,
	struct hfi_msg_session_hdr *pkt,
	struct msm_cvp_cb_info *info)
{
	struct session_msg *sess_msg;
	struct msm_cvp_inst *inst = NULL;
	struct msm_cvp_core *core;
	void *session_id;

	if (!pkt) {
		dprintk(CVP_ERR, "%s: invalid param\n", __func__);
		return -EINVAL;
	} else if (pkt->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int)) {
		dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size);
		return -E2BIG;
	}
	session_id = (void *)(uintptr_t)pkt->session_id;
	core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
	inst = cvp_get_inst_from_id(core, session_id);

	if (!inst) {
		dprintk(CVP_ERR, "%s: invalid session\n", __func__);
		return -EINVAL;
	}

	sess_msg = kmem_cache_alloc(inst->session_queue.msg_cache, GFP_KERNEL);
	if (sess_msg == NULL) {
		dprintk(CVP_ERR, "%s runs out msg cache memory\n", __func__);
		return -ENOMEM;
	}

	memcpy(&sess_msg->pkt, pkt, sizeof(struct hfi_msg_session_hdr));

	spin_lock(&inst->session_queue.lock);
	if (inst->session_queue.msg_count >= MAX_NUM_MSGS_PER_SESSION) {
		dprintk(CVP_ERR, "Reached session queue size limit\n");
		goto error_handle_msg;
	}
	list_add_tail(&sess_msg->node, &inst->session_queue.msgs);
	inst->session_queue.msg_count++;
	spin_unlock(&inst->session_queue.lock);

	wake_up_all(&inst->session_queue.wq);

	info->response_type = HAL_NO_RESP;

	return 0;

error_handle_msg:
	spin_unlock(&inst->session_queue.lock);
	kmem_cache_free(inst->session_queue.msg_cache, sess_msg);
	return -ENOMEM;
}

static int hfi_process_session_cvp_dme(u32 device_id,
	struct hfi_msg_session_cvp_dme_packet_type *pkt,
	struct msm_cvp_cb_info *info)
@@ -930,9 +1011,8 @@ static int hfi_process_session_cvp_dme(u32 device_id,
	if (!pkt) {
		dprintk(CVP_ERR, "%s: invalid param\n", __func__);
		return -EINVAL;
	} else if (pkt->size < sizeof(*pkt)) {
		dprintk(CVP_ERR,
				"%s: bad_pkt_size\n", __func__);
	} else if (pkt->size > sizeof(*pkt)) {
		dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size);
		return -E2BIG;
	}

@@ -1068,7 +1148,7 @@ int cvp_hfi_process_msg_packet(u32 device_id,
		return -EINVAL;
	}

	dprintk(CVP_DBG, "Parse response %#x\n", msg_hdr->packet);
	dprintk(CVP_DBG, "Received HFI MSG with type %d\n", msg_hdr->packet);
	switch (msg_hdr->packet) {
	case HFI_MSG_EVENT_NOTIFY:
		pkt_func = (pkt_func_def)hfi_process_event_notify;
@@ -1095,27 +1175,21 @@ int cvp_hfi_process_msg_packet(u32 device_id,
		pkt_func = (pkt_func_def)hfi_process_session_abort_done;
		break;
	case HFI_MSG_SESSION_CVP_OPERATION_CONFIG:
		dprintk(CVP_DBG,
			"Received HFI_MSG_SESSION_CVP_OPERATION_CONFIG from firmware");
		pkt_func =
			(pkt_func_def)hfi_process_session_cvp_operation_config;
		break;
	case HFI_MSG_SESSION_CVP_DFS:
		dprintk(CVP_DBG,
			"Received HFI_MSG_SESSION_CVP_DFS from firmware");
		pkt_func = (pkt_func_def)hfi_process_session_cvp_dfs;
		break;
	case HFI_MSG_SESSION_CVP_DME:
		dprintk(CVP_DBG,
			"Received HFI_MSG_SESSION_CVP_DME from firmware");
		pkt_func = (pkt_func_def)hfi_process_session_cvp_dme;
		break;
	case HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS:
		dprintk(CVP_DBG,
			"Received HFI_MSG_SESSION_CVP_PERSIST from firmware");
		pkt_func = (pkt_func_def)hfi_process_session_cvp_persist;
		break;

	case HFI_MSG_SESSION_CVP_DS:
		pkt_func = (pkt_func_def)hfi_process_session_cvp_msg;
		break;
	default:
		dprintk(CVP_DBG, "Unable to parse message: %#x\n",
				msg_hdr->packet);
+66 −5
Original line number Diff line number Diff line
@@ -217,6 +217,65 @@ static int msm_cvp_map_buf(struct msm_cvp_inst *inst,
	return rc;
}

static bool _cvp_msg_pending(struct msm_cvp_inst *inst,
			struct cvp_session_queue *sq,
			struct session_msg **msg)
{
	struct session_msg *mptr = NULL;
	bool result = false;

	spin_lock(&sq->lock);
	if (!kref_read(&inst->kref)) {
		/* The session is being deleted */
		spin_unlock(&sq->lock);
		*msg = NULL;
		return true;
	}
	result = list_empty(&sq->msgs);
	if (!result) {
		mptr = list_first_entry(&sq->msgs, struct session_msg, node);
		list_del_init(&mptr->node);
		sq->msg_count--;
	}
	spin_unlock(&sq->lock);
	*msg = mptr;
	return !result;
}


static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst,
			struct cvp_kmd_hfi_packet *out_pkt)
{
	unsigned long wait_time;
	struct session_msg *msg = NULL;
	struct cvp_session_queue *sq;

	if (!inst) {
		dprintk(CVP_ERR, "%s invalid session\n", __func__);
		return -EINVAL;
	}

	sq = &inst->session_queue;

	wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME);

	if (wait_event_timeout(sq->wq,
		_cvp_msg_pending(inst, sq, &msg), wait_time) == 0) {
		dprintk(CVP_ERR, "session queue wait timeout\n");
		return -ETIMEDOUT;
	}

	if (msg == NULL) {
		dprintk(CVP_ERR, "%s: session is deleted, no msg\n", __func__);
		return -EINVAL;
	}

	memcpy(out_pkt, &msg->pkt, sizeof(struct hfi_msg_session_hdr));
	kmem_cache_free(inst->session_queue.msg_cache, msg);

	return 0;
}

static int msm_cvp_session_process_hfi(
	struct msm_cvp_inst *inst,
	struct cvp_kmd_hfi_packet *in_pkt)
@@ -600,11 +659,6 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst,
	hdev = inst->core->device;
	print_client_buffer(CVP_DBG, "unregister", inst, buf);

	if (!buf->index) {
		dprintk(CVP_ERR, "Missing index when unregister buf\n");
		return 0;
	}

	mutex_lock(&inst->cvpbufs.lock);
	found = false;
	list_for_each_entry(cbuf, &inst->cvpbufs.list, list) {
@@ -690,6 +744,13 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg)
		rc = msm_cvp_send_cmd(inst, send_cmd);
		break;
	}
	case CVP_KMD_RECEIVE_MSG_PKT:
	{
		struct cvp_kmd_hfi_packet *out_pkt =
			(struct cvp_kmd_hfi_packet *)&arg->data.hfi_pkt;
		rc = msm_cvp_session_receive_hfi(inst, out_pkt);
		break;
	}
	case CVP_KMD_SEND_CMD_PKT:
	case CVP_KMD_HFI_DFS_CONFIG_CMD:
	case CVP_KMD_HFI_DFS_FRAME_CMD:
Loading