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

Commit 14912426 authored by Jilai Wang's avatar Jilai Wang
Browse files

msm: npu: Use spinlock for ipc write to avoid context switch



Use a spinlock to prevent context switch while sending ipc
command to firmware.

Change-Id: Ie0066bc410c9c1bc153cf9959721493aebff0424
Signed-off-by: default avatarJilai Wang <jilaiw@codeaurora.org>
parent 1193ebd5
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* SPDX-License-Identifier: GPL-2.0-only */
/*
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */
 */


#ifndef _NPU_COMMON_H
#ifndef _NPU_COMMON_H
@@ -134,7 +134,7 @@ struct npu_mbox {
};
};


/**
/**
 * struct npul_pwrlevel - Struct holding different pwrlevel info obtained from
 * struct npu_pwrlevel - Struct holding different pwrlevel info obtained
 * from dtsi file
 * from dtsi file
 * @pwr_level:           NPU power level
 * @pwr_level:           NPU power level
 * @freq[]:              NPU frequency vote in Hz
 * @freq[]:              NPU frequency vote in Hz
@@ -246,6 +246,7 @@ struct mbox_bridge_data {


struct npu_device {
struct npu_device {
	struct mutex dev_lock;
	struct mutex dev_lock;
	spinlock_t ipc_lock;


	struct platform_device *pdev;
	struct platform_device *pdev;


+8 −0
Original line number Original line Diff line number Diff line
@@ -74,6 +74,8 @@ static int npu_host_ipc_init_hfi(struct npu_device *npu_dev)
	uint32_t q_size = 0;
	uint32_t q_size = 0;
	uint32_t cur_start_offset = 0;
	uint32_t cur_start_offset = 0;


	spin_lock_init(&npu_dev->ipc_lock);

	reg_val = REGR(npu_dev, REG_NPU_FW_CTRL_STATUS);
	reg_val = REGR(npu_dev, REG_NPU_FW_CTRL_STATUS);


	/*
	/*
@@ -140,6 +142,7 @@ static int npu_host_ipc_init_hfi(struct npu_device *npu_dev)
	reg_val = REGR(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_STATUS);
	reg_val = REGR(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_STATUS);
	REGW(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_STATUS, reg_val |
	REGW(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_STATUS, reg_val |
		HOST_CTRL_STATUS_IPC_ADDRESS_READY_VAL);
		HOST_CTRL_STATUS_IPC_ADDRESS_READY_VAL);

	return status;
	return status;
}
}


@@ -149,13 +152,17 @@ static int npu_host_ipc_send_cmd_hfi(struct npu_device *npu_dev,
	int status = 0;
	int status = 0;
	uint8_t is_rx_req_set = 0;
	uint8_t is_rx_req_set = 0;
	uint32_t retry_cnt = 5;
	uint32_t retry_cnt = 5;
	unsigned long flags;


	spin_lock_irqsave(&npu_dev->ipc_lock, flags);
	status = ipc_queue_write(npu_dev, q_idx, (uint8_t *)cmd_ptr,
	status = ipc_queue_write(npu_dev, q_idx, (uint8_t *)cmd_ptr,
		&is_rx_req_set);
		&is_rx_req_set);


	if (status == -ENOSPC) {
	if (status == -ENOSPC) {
		do {
		do {
			spin_unlock_irqrestore(&npu_dev->ipc_lock, flags);
			msleep(20);
			msleep(20);
			spin_lock_irqsave(&npu_dev->ipc_lock, flags);
			status = ipc_queue_write(npu_dev, q_idx,
			status = ipc_queue_write(npu_dev, q_idx,
				(uint8_t *)cmd_ptr, &is_rx_req_set);
				(uint8_t *)cmd_ptr, &is_rx_req_set);
		} while ((status == -ENOSPC) && (--retry_cnt > 0));
		} while ((status == -ENOSPC) && (--retry_cnt > 0));
@@ -165,6 +172,7 @@ static int npu_host_ipc_send_cmd_hfi(struct npu_device *npu_dev,
		if (is_rx_req_set == 1)
		if (is_rx_req_set == 1)
			status = INTERRUPT_RAISE_NPU(npu_dev);
			status = INTERRUPT_RAISE_NPU(npu_dev);
	}
	}
	spin_unlock_irqrestore(&npu_dev->ipc_lock, flags);


	if (status)
	if (status)
		NPU_ERR("Cmd Msg put on Command Queue - FAILURE\n");
		NPU_ERR("Cmd Msg put on Command Queue - FAILURE\n");