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

Commit 1cb272dd authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: npu: Auto PIL and SSR update"

parents b56f51ac b486eaa4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -787,6 +787,8 @@ int npu_enable_irq(struct npu_device *npu_dev)
	}

	/* setup general irq */
	npu_cc_reg_write(npu_dev, NPU_CC_NPU_MASTERn_GENERAL_IRQ_CLEAR(0),
		RSC_SHUTDOWN_REQ_IRQ_ENABLE | RSC_BRINGUP_REQ_IRQ_ENABLE);
	reg_val = npu_cc_reg_read(npu_dev,
		NPU_CC_NPU_MASTERn_GENERAL_IRQ_OWNER(0));
	reg_val |= RSC_SHUTDOWN_REQ_IRQ_ENABLE | RSC_BRINGUP_REQ_IRQ_ENABLE;
@@ -797,8 +799,6 @@ int npu_enable_irq(struct npu_device *npu_dev)
	reg_val |= RSC_SHUTDOWN_REQ_IRQ_ENABLE | RSC_BRINGUP_REQ_IRQ_ENABLE;
	npu_cc_reg_write(npu_dev, NPU_CC_NPU_MASTERn_GENERAL_IRQ_ENABLE(0),
		reg_val);
	npu_cc_reg_write(npu_dev, NPU_CC_NPU_MASTERn_GENERAL_IRQ_CLEAR(0),
		RSC_SHUTDOWN_REQ_IRQ_ENABLE | RSC_BRINGUP_REQ_IRQ_ENABLE);
	for (i = 0; i < NPU_MAX_IRQ; i++) {
		if (npu_dev->irq[i].irq != 0) {
			enable_irq(npu_dev->irq[i].irq);
+73 −26
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
#define LOG_MSG_MSG_ID_INDEX     1

#define NPU_FW_TIMEOUT_POLL_INTERVAL_MS  20
#define NPU_FW_TIMEOUT_MS                1000
#define NPU_FW_TIMEOUT_MS                5000

/* -------------------------------------------------------------------------
 * File Scope Function Prototypes
@@ -61,8 +61,7 @@ static int npu_notify_aop(struct npu_device *npu_dev, bool on);
static int npu_notify_fw_pwr_state(struct npu_device *npu_dev,
	uint32_t pwr_level, bool post);
static int load_fw_nolock(struct npu_device *npu_dev);
static void disable_fw_nolock(struct npu_device *npu_dev, bool ssr,
	bool fw_alive);
static void disable_fw_nolock(struct npu_device *npu_dev);

/* -------------------------------------------------------------------------
 * Function Definitions - Init / Deinit
@@ -100,8 +99,21 @@ static int load_fw_nolock(struct npu_device *npu_dev)

	host_ctx->fw_state = FW_ENABLED;

	/* delay 3 seconds for cold boot complele */
	msleep(3000);
	reinit_completion(&host_ctx->fw_shutdown_done);
	ret = npu_notify_fw_pwr_state(npu_dev, NPU_PWRLEVEL_OFF, false);
	if (ret) {
		NPU_ERR("notify fw pwr off failed\n");
		goto load_fw_fail;
	}

	ret = wait_for_completion_timeout(
		&host_ctx->fw_shutdown_done, NW_CMD_TIMEOUT);
	if (!ret) {
		NPU_ERR("Wait for fw shutdown timedout\n");
		ret = -ETIMEDOUT;
	} else {
		ret = 0;
	}

load_fw_fail:
	npu_disable_irq(npu_dev);
@@ -206,10 +218,23 @@ int enable_fw(struct npu_device *npu_dev)

	NPU_DBG("NPU powers up\n");

	/* turn on auto ACK for warm boots up */
	npu_cc_reg_write(npu_dev, NPU_CC_NPU_CPC_RSC_CTRL, 3);
	reinit_completion(&host_ctx->fw_bringup_done);
	ret = npu_notify_fw_pwr_state(npu_dev, npu_dev->pwrctrl.active_pwrlevel,
		true);
	if (ret) {
		NPU_WARN("notify fw power state failed\n");
		NPU_ERR("notify fw power state failed\n");
		goto notify_fw_pwr_fail;
	}

	ret = wait_for_completion_interruptible_timeout(
		&host_ctx->fw_bringup_done, NW_CMD_TIMEOUT);
	if (!ret) {
		NPU_ERR("Wait for fw bringup timedout\n");
		ret = -ETIMEDOUT;
		goto notify_fw_pwr_fail;
	} else {
		ret = 0;
	}

@@ -223,6 +248,8 @@ int enable_fw(struct npu_device *npu_dev)

	return ret;

notify_fw_pwr_fail:
	npu_disable_irq(npu_dev);
enable_irq_fail:
	npu_disable_sys_cache(npu_dev);
enable_sys_cache_fail:
@@ -233,14 +260,16 @@ int enable_fw(struct npu_device *npu_dev)
	return ret;
}

static void disable_fw_nolock(struct npu_device *npu_dev, bool ssr,
	bool fw_alive)
static void disable_fw_nolock(struct npu_device *npu_dev)
{
	struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;

	if (!ssr && (host_ctx->fw_ref_cnt > 0))
		host_ctx->fw_ref_cnt--;
	if (!host_ctx->fw_ref_cnt) {
		NPU_WARN("fw_ref_cnt is 0\n");
		return;
	}

	host_ctx->fw_ref_cnt--;
	NPU_DBG("fw_ref_cnt %d\n", host_ctx->fw_ref_cnt);

	if (host_ctx->fw_state != FW_ENABLED) {
@@ -248,23 +277,20 @@ static void disable_fw_nolock(struct npu_device *npu_dev, bool ssr,
		return;
	}

	if ((host_ctx->fw_ref_cnt > 0) && !ssr)
	if (host_ctx->fw_ref_cnt > 0)
		return;

	/*
	 * if fw is still alive, notify fw before power off
	 * otherwise if ssr happens or notify fw returns failure
	 * delay 500 ms to make sure dsp has finished
	 * its own ssr handling.
	 */
	if (fw_alive) {
	/* turn on auto ACK for warm shuts down */
	npu_cc_reg_write(npu_dev, NPU_CC_NPU_CPC_RSC_CTRL, 3);
	reinit_completion(&host_ctx->fw_shutdown_done);
	if (npu_notify_fw_pwr_state(npu_dev, NPU_PWRLEVEL_OFF, false)) {
		NPU_WARN("notify fw pwr off failed\n");
		msleep(500);
	}
	} else {
		msleep(500);
	}

	if (!wait_for_completion_interruptible_timeout(
		&host_ctx->fw_shutdown_done, NW_CMD_TIMEOUT))
		NPU_ERR("Wait for fw shutdown timedout\n");

	npu_disable_irq(npu_dev);
	npu_disable_sys_cache(npu_dev);
@@ -281,7 +307,7 @@ void disable_fw(struct npu_device *npu_dev)
	struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;

	mutex_lock(&host_ctx->lock);
	disable_fw_nolock(npu_dev, false, true);
	disable_fw_nolock(npu_dev);
	mutex_unlock(&host_ctx->lock);
}

@@ -444,6 +470,8 @@ int npu_host_init(struct npu_device *npu_dev)
	memset(host_ctx, 0, sizeof(*host_ctx));
	init_completion(&host_ctx->misc_cmd_done);
	init_completion(&host_ctx->fw_deinit_done);
	init_completion(&host_ctx->fw_bringup_done);
	init_completion(&host_ctx->fw_shutdown_done);
	mutex_init(&host_ctx->lock);
	atomic_set(&host_ctx->ipc_trans_id, 1);

@@ -497,8 +525,9 @@ irqreturn_t npu_ipc_intr_hdlr(int irq, void *ptr)

irqreturn_t npu_general_intr_hdlr(int irq, void *ptr)
{
	uint32_t reg_val;
	uint32_t reg_val, ack_val;
	struct npu_device *npu_dev = (struct npu_device *)ptr;
	struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;

	NPU_DBG("NPU general irq %d\n", irq);

@@ -506,9 +535,28 @@ irqreturn_t npu_general_intr_hdlr(int irq, void *ptr)
		NPU_CC_NPU_MASTERn_GENERAL_IRQ_STATUS(0));
	NPU_DBG("GENERAL_IRQ_STATUS %x\n", reg_val);
	reg_val &= (RSC_SHUTDOWN_REQ_IRQ_STATUS | RSC_BRINGUP_REQ_IRQ_STATUS);
	ack_val = npu_cc_reg_read(npu_dev, NPU_CC_NPU_CPC_RSC_CTRL);

	if (reg_val & RSC_SHUTDOWN_REQ_IRQ_STATUS) {
		NPU_DBG("Send SHUTDOWN ACK\n");
		ack_val |= Q6SS_RSC_SHUTDOWN_ACK_EN;
	}

	if (reg_val & RSC_BRINGUP_REQ_IRQ_STATUS) {
		NPU_DBG("Send BRINGUP ACK\n");
		ack_val |= Q6SS_RSC_BRINGUP_ACK_EN;
	}

	npu_cc_reg_write(npu_dev, NPU_CC_NPU_CPC_RSC_CTRL, ack_val);
	npu_cc_reg_write(npu_dev,
		NPU_CC_NPU_MASTERn_GENERAL_IRQ_CLEAR(0), reg_val);

	if (reg_val & RSC_SHUTDOWN_REQ_IRQ_STATUS)
		complete(&host_ctx->fw_shutdown_done);

	if (reg_val & RSC_BRINGUP_REQ_IRQ_STATUS)
		complete(&host_ctx->fw_bringup_done);

	return IRQ_HANDLED;
}

@@ -611,7 +659,6 @@ static int host_error_hdlr(struct npu_device *npu_dev, bool force)
	NPU_DBG("firmware init complete\n");

	host_ctx->fw_state = FW_ENABLED;
	msleep(3000);

fw_start_done:
	/* mark all existing network to error state */
+3 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@
 * Defines
 * -------------------------------------------------------------------------
 */
#define NW_CMD_TIMEOUT_MS (1000 * 60 * 5) /* set for 5 minutes */
#define NW_CMD_TIMEOUT_MS (1000 * 5) /* set for 5 seconds */
#define NW_CMD_TIMEOUT msecs_to_jiffies(NW_CMD_TIMEOUT_MS)
#define NW_DEBUG_TIMEOUT_MS (1000 * 60 * 30) /* set for 30 minutes */
#define NW_DEBUG_TIMEOUT msecs_to_jiffies(NW_DEBUG_TIMEOUT_MS)
@@ -77,6 +77,8 @@ struct npu_host_ctx {
	struct workqueue_struct *wq;
	struct completion misc_cmd_done;
	struct completion fw_deinit_done;
	struct completion fw_bringup_done;
	struct completion fw_shutdown_done;
	int32_t network_num;
	struct npu_network networks[MAX_LOADED_NETWORK];
	bool sys_cache_disable;