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

Commit ae7f592c authored by Ruofei Ma's avatar Ruofei Ma Committed by George Shen
Browse files

msm: cvp: CVP DSP driver restructure for Lahaina



Restructure CVP DSP driver to enhance error handling path
and accommodate features for future needs.

Change-Id: Icae8110241fa9598a8d570cc1148a00834cda779
Signed-off-by: default avatarRuofei Ma <ruofeim@codeaurora.org>
Signed-off-by: default avatarGeorge Shen <sqiao@codeaurora.org>
parent 59d3346d
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/debugfs.h>
@@ -26,7 +26,6 @@
#include "msm_cvp_clocks.h"
#include "msm_cvp_dsp.h"

#define BASE_DEVICE_NUMBER 32
#define CLASS_NAME              "cvp"
#define DRIVER_NAME             "cvp"

@@ -34,18 +33,15 @@ struct msm_cvp_drv *cvp_driver;

static int cvp_open(struct inode *inode, struct file *filp)
{
	int rc;
	struct msm_cvp_core *core = container_of(inode->i_cdev,
		struct msm_cvp_core, cdev);
	struct msm_cvp_inst *inst;

	dprintk(CVP_DBG, "%s: Enter\n", __func__);

	rc = cvp_dsp_device_init();
	inst = msm_cvp_open(core->id, MSM_CVP_USER);
	if (!inst || rc) {
		dprintk(CVP_ERR,
		"Failed to create cvp instance rc=%d\n", rc);
	if (!inst) {
		dprintk(CVP_ERR, "Failed to create cvp instance\n");
		return -ENOMEM;
	}
	filp->private_data = inst;
@@ -551,8 +547,7 @@ static int __init msm_cvp_init(void)
{
	int rc = 0;

	cvp_driver = kzalloc(sizeof(*cvp_driver),
						GFP_KERNEL);
	cvp_driver = kzalloc(sizeof(*cvp_driver), GFP_KERNEL);
	if (!cvp_driver) {
		dprintk(CVP_ERR,
			"Failed to allocate memroy for msm_cvp_drv\n");
@@ -582,6 +577,10 @@ static int __init msm_cvp_init(void)
	cvp_driver->frame_buf_cache = KMEM_CACHE(msm_cvp_frame_buf, 0);
	cvp_driver->internal_buf_cache = KMEM_CACHE(msm_cvp_internal_buffer, 0);

	rc = cvp_dsp_device_init();
	if (rc)
		dprintk(CVP_WARN, "Failed to initialize DSP driver\n");

	return rc;
}

+1 −9
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#ifndef __H_CVP_CORE_HFI_H__
@@ -201,11 +201,6 @@ struct iris_resources {
	struct msm_cvp_fw fw;
};

enum dsp_flag {
	DSP_INIT = BIT(0),
	DSP_SUSPEND = BIT(1),
};

enum iris_hfi_state {
	IRIS_STATE_DEINIT = 1,
	IRIS_STATE_INIT,
@@ -229,7 +224,6 @@ struct iris_hfi_vpu_ops {
};

struct iris_hfi_device {
	struct list_head list;
	struct list_head sess_head;
	u32 version;
	u32 intr_status;
@@ -250,7 +244,6 @@ struct iris_hfi_device {
	struct cvp_mem_addr mem_addr;
	struct cvp_iface_q_info iface_queues[CVP_IFACEQ_NUMQ];
	struct cvp_iface_q_info dsp_iface_queues[CVP_IFACEQ_NUMQ];
	u32 dsp_flags;
	struct cvp_hal_data *cvp_hal_data;
	struct workqueue_struct *cvp_workq;
	struct workqueue_struct *iris_pm_workq;
@@ -267,7 +260,6 @@ struct iris_hfi_device {
	unsigned int skip_pc_count;
	struct msm_cvp_capability *sys_init_capabilities;
	struct iris_hfi_vpu_ops *vpu_ops;
	struct delayed_work dsp_init_work;
};

void cvp_iris_hfi_delete_device(void *device);
+4 −101
Original line number Diff line number Diff line
@@ -264,7 +264,6 @@ const int cvp_max_packets = 32;

static void iris_hfi_pm_handler(struct work_struct *work);
static DECLARE_DELAYED_WORK(iris_hfi_pm_work, iris_hfi_pm_handler);
static void dsp_init_work_handler(struct work_struct *work);
static inline int __resume(struct iris_hfi_device *device);
static inline int __suspend(struct iris_hfi_device *device);
static int __disable_regulators(struct iris_hfi_device *device);
@@ -420,41 +419,6 @@ static void __dump_packet(u8 *packet, enum cvp_msg_prio log_level)
	}
}

static int __dsp_send_hfi_queue(struct iris_hfi_device *device)
{
	int rc;

	if (msm_cvp_dsp_disable) {
		dprintk(CVP_WARN, "%s: DSP support is disabled\n", __func__);
		return 0;
	}

	if (!device->dsp_iface_q_table.mem_data.dma_handle) {
		dprintk(CVP_ERR, "%s: invalid dsm_handle\n", __func__);
		return -EINVAL;
	}

	if (device->dsp_flags & DSP_INIT) {
		dprintk(CVP_DBG, "%s: dsp already inited\n", __func__);
		return 0;
	}

	dprintk(CVP_DBG, "%s: hfi queue %#llx size %d\n",
		__func__, device->dsp_iface_q_table.mem_data.dma_handle,
		device->dsp_iface_q_table.mem_data.size);
	rc = cvp_dsp_send_cmd_hfi_queue(
		(phys_addr_t *)device->dsp_iface_q_table.mem_data.dma_handle,
		device->dsp_iface_q_table.mem_data.size, device);
	if (rc) {
		dprintk(CVP_ERR, "%s: dsp hfi queue init failed\n", __func__);
		return rc;
	}

	device->dsp_flags |= DSP_INIT;
	dprintk(CVP_DBG, "%s: dsp inited\n", __func__);
	return rc;
}

static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
{
	int rc;
@@ -463,12 +427,6 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
	if (msm_cvp_dsp_disable)
		return 0;

	if (!(device->dsp_flags & DSP_INIT))
		return 0;

	if (device->dsp_flags & DSP_SUSPEND)
		return 0;

	list_for_each_entry(temp, &device->sess_head, list) {
		/* if forceful suspend, don't check session pause info */
		if (force)
@@ -491,7 +449,6 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
		return -EINVAL;
	}

	device->dsp_flags |= DSP_SUSPEND;
	dprintk(CVP_DBG, "%s: dsp suspended\n", __func__);
	return 0;
}
@@ -503,11 +460,6 @@ static int __dsp_resume(struct iris_hfi_device *device, u32 flags)
	if (msm_cvp_dsp_disable)
		return 0;

	if (!(device->dsp_flags & DSP_SUSPEND)) {
		dprintk(CVP_DBG, "%s: dsp not suspended\n", __func__);
		return 0;
	}

	dprintk(CVP_DBG, "%s: resume dsp\n", __func__);
	rc = cvp_dsp_resume(flags);
	if (rc) {
@@ -517,7 +469,6 @@ static int __dsp_resume(struct iris_hfi_device *device, u32 flags)
		return rc;
	}

	device->dsp_flags &= ~DSP_SUSPEND;
	dprintk(CVP_DBG, "%s: dsp resumed\n", __func__);
	return rc;
}
@@ -529,13 +480,6 @@ static int __dsp_shutdown(struct iris_hfi_device *device, u32 flags)
	if (msm_cvp_dsp_disable)
		return 0;

	cvp_dsp_set_cvp_ssr();

	if (!(device->dsp_flags & DSP_INIT)) {
		dprintk(CVP_WARN, "%s: dsp not inited\n", __func__);
		return 0;
	}

	dprintk(CVP_DBG, "%s: shutdown dsp\n", __func__);
	rc = cvp_dsp_shutdown(flags);
	if (rc) {
@@ -545,7 +489,6 @@ static int __dsp_shutdown(struct iris_hfi_device *device, u32 flags)
		WARN_ON(1);
	}

	device->dsp_flags &= ~DSP_INIT;
	dprintk(CVP_DBG, "%s: dsp shutdown successful\n", __func__);
	return rc;
}
@@ -1992,43 +1935,6 @@ static int __sys_set_power_control(struct iris_hfi_device *device,
	return 0;
}

static void dsp_init_work_handler(struct work_struct *work)
{
	int rc = 0;
	static int retry_count;
	struct iris_hfi_device *device;

	if (!work) {
		dprintk(CVP_ERR, "%s: NULL device\n", __func__);
		return;
	}

	device = container_of(work, struct iris_hfi_device, dsp_init_work.work);
	if (!device) {
		dprintk(CVP_ERR, "%s: NULL device\n", __func__);
		return;
	}

	dprintk(CVP_PROF, "Entering %s\n", __func__);

	mutex_lock(&device->lock);
	rc = __dsp_send_hfi_queue(device);
	mutex_unlock(&device->lock);

	if (rc) {
		if (retry_count > MAX_DSP_INIT_ATTEMPTS) {
			dprintk(CVP_ERR, "%s: max trials exceeded\n", __func__);
			return;
		}
		dprintk(CVP_PROF, "%s: Attempt to init DSP %d\n",
			__func__, retry_count);

		schedule_delayed_work(&device->dsp_init_work,
				msecs_to_jiffies(CVP_MAX_WAIT_TIME));
		++retry_count;
	}
}

static int iris_hfi_core_init(void *device)
{
	int rc = 0;
@@ -2115,13 +2021,12 @@ static int iris_hfi_core_init(void *device)
		pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY,
				dev->res->pm_qos_latency_us);

	rc = __dsp_send_hfi_queue(device);
	if (rc)
		schedule_delayed_work(&dev->dsp_init_work,
				msecs_to_jiffies(CVP_MAX_WAIT_TIME));
	mutex_unlock(&dev->lock);

	cvp_dsp_send_hfi_queue();

	dprintk(CVP_DBG, "Core inited successfully\n");
	mutex_unlock(&dev->lock);

	return 0;
err_core_init:
	__set_state(dev, IRIS_STATE_DEINIT);
@@ -4574,8 +4479,6 @@ static struct iris_hfi_device *__add_device(u32 device_id,
	mutex_init(&hdevice->lock);
	INIT_LIST_HEAD(&hdevice->sess_head);

	INIT_DELAYED_WORK(&hdevice->dsp_init_work, dsp_init_work_handler);

	return hdevice;

err_cleanup:
+326 −413

File changed.

Preview size limit exceeded, changes collapsed.

+43 −30
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

#ifndef MSM_CVP_DSP_H
@@ -13,18 +13,48 @@
#define CVP_APPS_DSP_GLINK_GUID "cvp-glink-apps-dsp"
#define CVP_APPS_DSP_SMD_GUID "cvp-smd-apps-dsp"

/*
 * API for CVP driver to send physical address to dsp driver
 * @param phys_addr
 * Physical address of command message queue
 * that needs to be mapped to CDSP.
 * It should be allocated from CMA adsp_mem region.
 *
 * @param size_in_bytes
 * Size in bytes of command message queue
 */
int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr,
	uint32_t size_in_bytes, struct iris_hfi_device *device);
#define VMID_CDSP_Q6 (30)
#define HLOS_VM_NUM 1
#define DSP_VM_NUM 2
#define CVP_DSP_MAX_RESERVED 5
#define CVP_DSP_RESPONSE_TIMEOUT 1000

int cvp_dsp_device_init(void);
void cvp_dsp_device_exit(void);
void cvp_dsp_send_hfi_queue(void);

enum DSP_COMMAND {
	CVP_DSP_SEND_HFI_QUEUE = 0,
	CVP_DSP_SUSPEND = 1,
	CVP_DSP_RESUME = 2,
	CVP_DSP_SHUTDOWN = 3,
	CVP_DSP_REGISTER_BUFFER = 4,
	CVP_DSP_DEREGISTER_BUFFER = 5,
	CVP_DSP_MAX_CMD
};

struct cvp_dsp_cmd_msg {
	uint32_t type;
	int32_t ret;
	uint64_t msg_ptr;
	uint32_t msg_ptr_len;
	uint32_t buff_fd_iova;
	uint32_t buff_index;
	uint32_t buff_size;
	uint32_t session_id;
	int32_t ddr_type;
	uint32_t buff_fd;
	uint32_t buff_offset;
	uint32_t buff_fd_size;
	uint32_t reserved1;
	uint32_t reserved2;
};

struct cvp_dsp_rsp_msg {
	uint32_t type;
	int32_t ret;
	uint32_t reserved[CVP_DSP_MAX_RESERVED];
};

/*
 * API for CVP driver to suspend CVP session during
@@ -53,13 +83,6 @@ int cvp_dsp_resume(uint32_t session_flag);
 */
int cvp_dsp_shutdown(uint32_t session_flag);

/*
 * API for CVP driver to set CVP status during
 * cvp subsystem error.
 *
 */
void cvp_dsp_set_cvp_ssr(void);

/*
 * API to register iova buffer address with CDSP
 *
@@ -92,15 +115,5 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd,
			uint32_t buff_offset, uint32_t buff_index,
			uint32_t buff_fd_iova);

/*
 * API to initialize CPU and DSP driver interface
 */
int cvp_dsp_device_init(void);

/*
 * API to deinitilized CPU and DSP driver interface
 */
void cvp_dsp_device_exit(void);

#endif // MSM_CVP_DSP_H
Loading