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

Commit 0d898c47 authored by Da Hoon Pyun's avatar Da Hoon Pyun
Browse files

msm: npu: Add support to get firmware capabilities



Add new property ID MSM_NPU_PROP_ID_FW_GETCAPS to retrieve firmware
capabilities. In order to allow get/set firmware properties when no
network is loaded, firmware will be enabled before sending command
to firmware and disabled afterwards.

Change-Id: I40d12c96dba6dd18e5eee147f2729b707aa1ef13
Signed-off-by: default avatarDa Hoon Pyun <dpyun@codeaurora.org>
parent 3a7043cb
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -1363,12 +1363,6 @@ static int npu_set_fw_state(struct npu_client *client, uint32_t enable)
	struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;
	int rc = 0;

	if (host_ctx->network_num > 0) {
		NPU_ERR("Need to unload network first\n");
		mutex_unlock(&npu_dev->dev_lock);
		return -EINVAL;
	}

	if (enable) {
		NPU_DBG("enable fw\n");
		rc = enable_fw(npu_dev);
@@ -1378,9 +1372,6 @@ static int npu_set_fw_state(struct npu_client *client, uint32_t enable)
			host_ctx->npu_init_cnt++;
			NPU_DBG("npu_init_cnt %d\n",
				host_ctx->npu_init_cnt);
			/* set npu to lowest power level */
			if (npu_set_uc_power_level(npu_dev, 1))
				NPU_WARN("Failed to set uc power level\n");
		}
	} else if (host_ctx->npu_init_cnt > 0) {
		NPU_DBG("disable fw\n");
@@ -1477,7 +1468,7 @@ static int npu_get_property(struct npu_client *client,
	default:
		ret = npu_host_get_fw_property(client->npu_dev, &prop);
		if (ret) {
			NPU_ERR("npu_host_set_fw_property failed\n");
			NPU_ERR("npu_host_get_fw_property failed\n");
			return ret;
		}
		break;
+94 −11
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ static void npu_dequeue_misc_cmd(struct npu_host_ctx *ctx,
	struct npu_misc_cmd *cmd);
static struct npu_misc_cmd *npu_find_misc_cmd(struct npu_host_ctx *ctx,
	uint32_t trans_id);
static int npu_get_fw_caps(struct npu_device *npu_dev);

/* -------------------------------------------------------------------------
 * Function Definitions - Init / Deinit
@@ -218,6 +219,37 @@ static int load_fw_nolock(struct npu_device *npu_dev, bool enable)
	return ret;
}

static int npu_get_fw_caps(struct npu_device *npu_dev)
{
	int ret = 0, i;
	struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;

	if (host_ctx->fw_caps_valid) {
		NPU_DBG("cached fw caps available\n");
		return ret;
	}

	memset(&host_ctx->fw_caps, 0, sizeof(host_ctx->fw_caps));
	host_ctx->fw_caps.prop_id = MSM_NPU_PROP_ID_FW_GETCAPS;
	host_ctx->fw_caps.num_of_params = PROP_PARAM_MAX_SIZE;

	ret = npu_host_get_fw_property(npu_dev, &host_ctx->fw_caps);
	if (!ret) {
		NPU_DBG("Get fw caps successfully\n");
		host_ctx->fw_caps_valid = true;

		for (i = 0; i < host_ctx->fw_caps.num_of_params; i++)
			NPU_INFO("fw caps %d:%x\n", i,
				host_ctx->fw_caps.prop_param[i]);
	} else {
		/* save the return code */
		host_ctx->fw_caps_err_code = ret;
		NPU_ERR("get fw caps failed %d\n", ret);
	}

	return ret;
}

static void npu_load_fw_work(struct work_struct *work)
{
	int ret;
@@ -231,8 +263,12 @@ static void npu_load_fw_work(struct work_struct *work)
	ret = load_fw_nolock(npu_dev, false);
	mutex_unlock(&host_ctx->lock);

	if (ret)
	if (ret) {
		NPU_ERR("load fw failed %d\n", ret);
		return;
	}

	npu_get_fw_caps(npu_dev);
}

int load_fw(struct npu_device *npu_dev)
@@ -272,6 +308,8 @@ int unload_fw(struct npu_device *npu_dev)

	subsystem_put_local(host_ctx->subsystem_handle);
	host_ctx->fw_state = FW_UNLOADED;
	host_ctx->fw_caps_valid = false;
	host_ctx->fw_caps_err_code = 0;
	NPU_DBG("fw is unloaded\n");
	mutex_unlock(&host_ctx->lock);

@@ -769,6 +807,8 @@ int npu_host_init(struct npu_device *npu_dev)

	INIT_LIST_HEAD(&host_ctx->misc_cmd_list);
	host_ctx->auto_pil_disable = false;
	host_ctx->fw_caps_valid = false;
	host_ctx->fw_caps_err_code = 0;

	return 0;

@@ -2155,7 +2195,13 @@ int32_t npu_host_set_fw_property(struct npu_device *npu_dev,
		break;
	default:
		NPU_ERR("unsupported property %d\n", property->prop_id);
		goto set_prop_exit;
		goto free_prop_packet;
	}

	ret = enable_fw(npu_dev);
	if (ret) {
		NPU_ERR("failed to enable fw\n");
		goto free_prop_packet;
	}

	prop_packet->header.cmd_type = NPU_IPC_CMD_SET_PROPERTY;
@@ -2170,16 +2216,17 @@ int32_t npu_host_set_fw_property(struct npu_device *npu_dev,
	for (i = 0; i < num_of_params; i++)
		prop_packet->prop_param[i] = property->prop_param[i];

	mutex_lock(&host_ctx->lock);
	misc_cmd = npu_alloc_misc_cmd(host_ctx);
	if (!misc_cmd) {
		NPU_ERR("Can't allocate misc_cmd\n");
		ret = -ENOMEM;
		goto set_prop_exit;
		goto disable_fw;
	}

	misc_cmd->cmd_type = NPU_IPC_CMD_SET_PROPERTY;
	misc_cmd->trans_id = prop_packet->header.trans_id;

	mutex_lock(&host_ctx->lock);
	npu_queue_misc_cmd(host_ctx, misc_cmd);

	ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_APPS_EXEC,
@@ -2213,10 +2260,13 @@ int32_t npu_host_set_fw_property(struct npu_device *npu_dev,

free_misc_cmd:
	npu_dequeue_misc_cmd(host_ctx, misc_cmd);
	npu_free_misc_cmd(host_ctx, misc_cmd);
set_prop_exit:
	mutex_unlock(&host_ctx->lock);
	npu_free_misc_cmd(host_ctx, misc_cmd);
disable_fw:
	disable_fw(npu_dev);
free_prop_packet:
	kfree(prop_packet);

	return ret;
}

@@ -2234,6 +2284,15 @@ int32_t npu_host_get_fw_property(struct npu_device *npu_dev,
		NPU_ERR("Not supported fw property id %x\n",
			property->prop_id);
		return -EINVAL;
	} else if (property->prop_id == MSM_NPU_PROP_ID_FW_GETCAPS) {
		if (host_ctx->fw_caps_valid) {
			NPU_DBG("return cached fw_caps\n");
			memcpy(property, &host_ctx->fw_caps, sizeof(*property));
			return 0;
		} else if (host_ctx->fw_caps_err_code) {
			NPU_DBG("return cached error code\n");
			return host_ctx->fw_caps_err_code;
		}
	}

	num_of_params = min_t(uint32_t, property->num_of_params,
@@ -2244,6 +2303,12 @@ int32_t npu_host_get_fw_property(struct npu_device *npu_dev,
	if (!prop_packet)
		return -ENOMEM;

	ret = enable_fw(npu_dev);
	if (ret) {
		NPU_ERR("failed to enable fw\n");
		goto free_prop_packet;
	}

	prop_packet->header.cmd_type = NPU_IPC_CMD_GET_PROPERTY;
	prop_packet->header.size = pkt_size;
	prop_packet->header.trans_id =
@@ -2256,16 +2321,17 @@ int32_t npu_host_get_fw_property(struct npu_device *npu_dev,
	for (i = 0; i < num_of_params; i++)
		prop_packet->prop_param[i] = property->prop_param[i];

	mutex_lock(&host_ctx->lock);
	misc_cmd = npu_alloc_misc_cmd(host_ctx);
	if (!misc_cmd) {
		NPU_ERR("Can't allocate misc_cmd\n");
		ret = -ENOMEM;
		goto get_prop_exit;
		goto disable_fw;
	}

	misc_cmd->cmd_type = NPU_IPC_CMD_GET_PROPERTY;
	misc_cmd->trans_id = prop_packet->header.trans_id;

	mutex_lock(&host_ctx->lock);
	npu_queue_misc_cmd(host_ctx, misc_cmd);

	ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_APPS_EXEC,
@@ -2294,26 +2360,43 @@ int32_t npu_host_get_fw_property(struct npu_device *npu_dev,
	}

	ret = misc_cmd->ret_status;
	prop_from_fw = &misc_cmd->u.prop;
	if (!ret) {
		/* Return prop data retrieved from fw to user */
		prop_from_fw = &misc_cmd->u.prop;
		if (property->prop_id == prop_from_fw->prop_id &&
			property->network_hdl == prop_from_fw->network_hdl) {
			num_of_params = min_t(uint32_t,
				prop_from_fw->num_of_params,
				(uint32_t)PROP_PARAM_MAX_SIZE);
			property->num_of_params = num_of_params;
			for (i = 0; i < num_of_params; i++)
				property->prop_param[i] =
					prop_from_fw->prop_param[i];
		} else {
			NPU_WARN("Not Match: id %x:%x hdl %x:%x\n",
				property->prop_id, prop_from_fw->prop_id,
				property->network_hdl,
				prop_from_fw->network_hdl);
			property->num_of_params = 0;
		}
	} else {
		NPU_ERR("get fw property failed %d\n", ret);
		NPU_ERR("prop_id: %x\n", prop_from_fw->prop_id);
		NPU_ERR("network_hdl: %x\n", prop_from_fw->network_hdl);
		NPU_ERR("param_num: %x\n", prop_from_fw->num_of_params);
		for (i = 0; i < prop_from_fw->num_of_params; i++)
			NPU_ERR("%x\n", prop_from_fw->prop_param[i]);
	}

free_misc_cmd:
	npu_dequeue_misc_cmd(host_ctx, misc_cmd);
	npu_free_misc_cmd(host_ctx, misc_cmd);
get_prop_exit:
	mutex_unlock(&host_ctx->lock);
	npu_free_misc_cmd(host_ctx, misc_cmd);
disable_fw:
	disable_fw(npu_dev);
free_prop_packet:
	kfree(prop_packet);

	return ret;
}

+4 −0
Original line number Diff line number Diff line
@@ -147,6 +147,10 @@ struct npu_host_ctx {
	bool bridge_mbox_pwr_on;
	void *ipc_msg_buf;
	struct list_head misc_cmd_list;

	struct msm_npu_property fw_caps;
	bool fw_caps_valid;
	uint32_t fw_caps_err_code;
};

struct npu_device;
+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@
#define MSM_NPU_PROP_ID_CLK_GATING_MODE (MSM_NPU_FW_PROP_ID_START + 2)
#define MSM_NPU_PROP_ID_HW_VERSION (MSM_NPU_FW_PROP_ID_START + 3)
#define MSM_NPU_PROP_ID_FW_VERSION (MSM_NPU_FW_PROP_ID_START + 4)
#define MSM_NPU_PROP_ID_FW_GETCAPS (MSM_NPU_FW_PROP_ID_START + 5)

/* features supported by driver */
#define MSM_NPU_FEATURE_MULTI_EXECUTE  0x1