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

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

Merge "msm: npu: Adjust timing to send notification to DSP"

parents 55dc6f88 a7d0abbf
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -269,7 +269,7 @@ int npu_set_uc_power_level(struct npu_device *npu_dev,
	uint32_t pwr_level);

int fw_init(struct npu_device *npu_dev);
void fw_deinit(struct npu_device *npu_dev, bool ssr);
void fw_deinit(struct npu_device *npu_dev, bool ssr, bool fw_alive);
int npu_notify_cdsprm_cxlimit_activity(struct npu_device *npu_dev, bool enable);

#endif /* _NPU_COMMON_H */
+1 −1
Original line number Diff line number Diff line
@@ -375,7 +375,7 @@ static ssize_t npu_debug_ctrl_write(struct file *file,
			pr_info("error in fw_init\n");
	} else if (strcmp(buf, "off") == 0) {
		pr_info("triggering fw_deinit\n");
		fw_deinit(npu_dev, false);
		fw_deinit(npu_dev, false, true);
	} else if (strcmp(buf, "ssr") == 0) {
		pr_info("trigger error irq\n");
		if (npu_enable_core_power(npu_dev))
+2 −0
Original line number Diff line number Diff line
@@ -1114,6 +1114,8 @@ static int npu_close(struct inode *inode, struct file *file)
	struct npu_client *client = file->private_data;
	struct npu_kevent *kevent;

	npu_host_cleanup_networks(client);

	while (!list_empty(&client->evt_list)) {
		kevent = list_first_entry(&client->evt_list,
			struct npu_kevent, list);
+6 −1
Original line number Diff line number Diff line
@@ -292,11 +292,13 @@ int npu_mem_map(struct npu_client *client, int buf_hdl, uint32_t size,
		ion_buf->table->nents, DMA_BIDIRECTIONAL);
	ion_buf->iova = ion_buf->table->sgl->dma_address;
	ion_buf->size = ion_buf->table->sgl->dma_length;
	*addr = ion_buf->iova;
	pr_debug("mapped mem addr:0x%llx size:0x%x\n", ion_buf->iova,
		ion_buf->size);
map_end:
	if (ret)
		npu_mem_unmap(client, buf_hdl, 0);

	*addr = ion_buf->iova;
	return ret;
}

@@ -356,6 +358,9 @@ void npu_mem_unmap(struct npu_client *client, int buf_hdl, uint64_t addr)
	if (ion_buf->dma_buf)
		dma_buf_put(ion_buf->dma_buf);
	npu_dev->smmu_ctx.attach_cnt--;

	pr_debug("unmapped mem addr:0x%llx size:0x%x\n", ion_buf->iova,
		ion_buf->size);
	npu_free_npu_ion_buffer(client, buf_hdl);
}

+43 −11
Original line number Diff line number Diff line
@@ -156,15 +156,15 @@ int fw_init(struct npu_device *npu_dev)
		goto wait_fw_ready_fail;
	}

	npu_notify_dsp(npu_dev, true);
	host_ctx->fw_state = FW_ENABLED;
	host_ctx->fw_error = false;
	host_ctx->fw_ref_cnt++;
	reinit_completion(&host_ctx->fw_deinit_done);

	mutex_unlock(&host_ctx->lock);
	pr_debug("firmware init complete\n");

	npu_notify_dsp(npu_dev, true);

	/* Set logging state */
	if (!npu_hw_log_enabled()) {
		pr_debug("fw logging disabled\n");
@@ -187,7 +187,7 @@ int fw_init(struct npu_device *npu_dev)
	return ret;
}

void fw_deinit(struct npu_device *npu_dev, bool ssr)
void fw_deinit(struct npu_device *npu_dev, bool ssr, bool fw_alive)
{
	struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;
	struct ipc_cmd_shutdown_pkt cmd_shutdown_pkt;
@@ -213,7 +213,7 @@ void fw_deinit(struct npu_device *npu_dev, bool ssr)

	npu_disable_irq(npu_dev);

	if (!ssr) {
	if (fw_alive) {
		/* Command header */
		cmd_shutdown_pkt.header.cmd_type = NPU_IPC_CMD_SHUTDOWN;
		cmd_shutdown_pkt.header.size =
@@ -246,11 +246,11 @@ void fw_deinit(struct npu_device *npu_dev, bool ssr)
	host_ctx->fw_state = FW_DISABLED;

	/*
	 * if it's not in ssr mode, notify dsp before power off
	 * if fw is still alive, notify dsp before power off
	 * otherwise delay 500 ms to make sure dsp has finished
	 * its own ssr handling.
	 */
	if (!ssr)
	if (fw_alive)
		npu_notify_dsp(npu_dev, false);
	else
		msleep(500);
@@ -339,7 +339,7 @@ static int host_error_hdlr(struct npu_device *npu_dev, bool force)
	if (host_ctx->wdg_irq_sts)
		pr_info("watchdog irq triggered\n");

	fw_deinit(npu_dev, true);
	fw_deinit(npu_dev, true, force);
	host_ctx->wdg_irq_sts = 0;
	host_ctx->err_irq_sts = 0;

@@ -1169,7 +1169,7 @@ int32_t npu_host_load_network(struct npu_client *client,
	free_network(host_ctx, client, network->id);
err_deinit_fw:
	mutex_unlock(&host_ctx->lock);
	fw_deinit(npu_dev, false);
	fw_deinit(npu_dev, false, true);
	return ret;
}

@@ -1221,6 +1221,7 @@ int32_t npu_host_load_network_v2(struct npu_client *client,

	/* verify mapped physical address */
	if (!npu_mem_verify_addr(client, network->phy_add)) {
		pr_err("Invalid network address %llx\n", network->phy_add);
		ret = -EINVAL;
		goto error_free_network;
	}
@@ -1295,7 +1296,7 @@ int32_t npu_host_load_network_v2(struct npu_client *client,
	free_network(host_ctx, client, network->id);
err_deinit_fw:
	mutex_unlock(&host_ctx->lock);
	fw_deinit(npu_dev, false);
	fw_deinit(npu_dev, false, true);
	return ret;
}

@@ -1399,7 +1400,7 @@ int32_t npu_host_unload_network(struct npu_client *client,
	if (ret)
		pr_err("network unload failed to set power level\n");
	mutex_unlock(&host_ctx->lock);
	fw_deinit(npu_dev, false);
	fw_deinit(npu_dev, false, true);
	return ret;
}

@@ -1732,7 +1733,38 @@ int32_t npu_host_loopback_test(struct npu_device *npu_dev)
	}

loopback_exit:
	fw_deinit(npu_dev, false);
	fw_deinit(npu_dev, false, true);

	return ret;
}

void npu_host_cleanup_networks(struct npu_client *client)
{
	int i;
	struct npu_device *npu_dev = client->npu_dev;
	struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;
	struct msm_npu_unload_network_ioctl unload_req;
	struct msm_npu_unmap_buf_ioctl unmap_req;
	struct npu_network *network;
	struct npu_ion_buf *ion_buf;

	for (i = 0; i < MAX_LOADED_NETWORK; i++) {
		network = &host_ctx->networks[i];
		if (network->client == client) {
			pr_warn("network %d is not unloaded before close\n",
				network->network_hdl);
			unload_req.network_hdl = network->network_hdl;
			npu_host_unload_network(client, &unload_req);
		}
	}

	/* unmap all remaining buffers */
	while (!list_empty(&client->mapped_buffer_list)) {
		ion_buf = list_first_entry(&client->mapped_buffer_list,
			struct npu_ion_buf, list);
		pr_warn("unmap buffer %x:%x\n", ion_buf->fd, ion_buf->iova);
		unmap_req.buf_ion_hdl = ion_buf->fd;
		unmap_req.npu_phys_addr = ion_buf->iova;
		npu_host_unmap_buf(client, &unmap_req);
	}
}
Loading