Merge "msm: npu: Power off npu until cpc power is off"

This commit is contained in:
qctecmdr 2019-09-12 15:41:04 -07:00 committed by Gerrit - the friendly Code Review server
commit ee486def3b
6 changed files with 50 additions and 26 deletions

View File

@ -245,7 +245,7 @@ struct npu_device {
struct npu_io_data core_io;
struct npu_io_data tcm_io;
struct npu_io_data cc_io;
struct npu_io_data qdsp_io;
struct npu_io_data tcsr_io;
struct npu_io_data apss_shared_io;
struct npu_io_data qfprom_io;

View File

@ -2174,23 +2174,23 @@ static int npu_probe(struct platform_device *pdev)
res->start, npu_dev->cc_io.base);
res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "qdsp");
IORESOURCE_MEM, "tcsr");
if (!res) {
NPU_ERR("unable to get qdsp resource\n");
NPU_ERR("unable to get tcsr_mutex resource\n");
rc = -ENODEV;
goto error_get_dev_num;
}
npu_dev->qdsp_io.size = resource_size(res);
npu_dev->qdsp_io.phy_addr = res->start;
npu_dev->qdsp_io.base = devm_ioremap(&pdev->dev, res->start,
npu_dev->qdsp_io.size);
if (unlikely(!npu_dev->qdsp_io.base)) {
NPU_ERR("unable to map qdsp\n");
npu_dev->tcsr_io.size = resource_size(res);
npu_dev->tcsr_io.phy_addr = res->start;
npu_dev->tcsr_io.base = devm_ioremap(&pdev->dev, res->start,
npu_dev->tcsr_io.size);
if (unlikely(!npu_dev->tcsr_io.base)) {
NPU_ERR("unable to map tcsr\n");
rc = -ENOMEM;
goto error_get_dev_num;
}
NPU_DBG("qdsp phy address=0x%llx virt=%pK\n",
res->start, npu_dev->qdsp_io.base);
NPU_DBG("tcsr phy address=0x%llx virt=%pK\n",
res->start, npu_dev->tcsr_io.base);
res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "apss_shared");

View File

@ -72,4 +72,7 @@
#define NPU_CC_NPU_MASTERn_WDOG_BITE_IRQ_OWNER(n) (0x0006010+4*(n))
#define NPU_CC_NPU_MASTERn_WDOG_BITE_IRQ_STATUS(n) (0x00009030+0x1000*(n))
#define TCSR_NPU_CPC_PWR_ON (0x0003700C)
#define NPU_CPC_PWR_ON (1 << 0)
#endif /* NPU_HW_H */

View File

@ -34,20 +34,14 @@ void npu_core_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val)
__iowmb();
}
uint32_t npu_qdsp_reg_read(struct npu_device *npu_dev, uint32_t off)
uint32_t npu_tcsr_reg_read(struct npu_device *npu_dev, uint32_t off)
{
uint32_t ret = 0;
ret = readl(npu_dev->qdsp_io.base + off);
ret = readl_relaxed(npu_dev->tcsr_io.base + off);
return ret;
}
void npu_qdsp_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val)
{
writel_relaxed(val, npu_dev->qdsp_io.base + off);
__iowmb();
}
uint32_t npu_apss_shared_reg_read(struct npu_device *npu_dev, uint32_t off)
{
uint32_t ret = 0;

View File

@ -50,8 +50,7 @@ typedef irqreturn_t (*intr_hdlr_fn)(int32_t irq, void *ptr);
*/
uint32_t npu_core_reg_read(struct npu_device *npu_dev, uint32_t off);
void npu_core_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val);
uint32_t npu_qdsp_reg_read(struct npu_device *npu_dev, uint32_t off);
void npu_qdsp_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val);
uint32_t npu_tcsr_reg_read(struct npu_device *npu_dev, uint32_t off);
uint32_t npu_apss_shared_reg_read(struct npu_device *npu_dev, uint32_t off);
void npu_apss_shared_reg_write(struct npu_device *npu_dev, uint32_t off,
uint32_t val);

View File

@ -40,6 +40,7 @@ static void npu_update_pwr_work(struct work_struct *work);
static void turn_off_fw_logging(struct npu_device *npu_dev);
static int wait_for_status_ready(struct npu_device *npu_dev,
uint32_t status_reg, uint32_t status_bits);
static int wait_npu_cpc_power_off(struct npu_device *npu_dev);
static struct npu_network *alloc_network(struct npu_host_ctx *ctx,
struct npu_client *client);
static struct npu_network *get_network_by_hdl(struct npu_host_ctx *ctx,
@ -70,6 +71,28 @@ static void disable_fw_nolock(struct npu_device *npu_dev);
* Function Definitions - Init / Deinit
* -------------------------------------------------------------------------
*/
static int wait_npu_cpc_power_off(struct npu_device *npu_dev)
{
uint32_t reg_val = NPU_CPC_PWR_ON;
uint32_t wait_cnt = 0, max_wait_ms;
max_wait_ms = NPU_FW_TIMEOUT_MS;
while (reg_val & NPU_CPC_PWR_ON) {
wait_cnt += NPU_FW_TIMEOUT_POLL_INTERVAL_MS;
if (wait_cnt >= max_wait_ms) {
NPU_ERR("timeout wait for cpc power off\n");
return -EPERM;
}
msleep(NPU_FW_TIMEOUT_POLL_INTERVAL_MS);
reg_val = npu_tcsr_reg_read(npu_dev, TCSR_NPU_CPC_PWR_ON);
};
NPU_DBG("npu cpc powers off\n");
return 0;
}
static int load_fw_nolock(struct npu_device *npu_dev, bool enable)
{
struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;
@ -138,7 +161,7 @@ static int load_fw_nolock(struct npu_device *npu_dev, bool enable)
NPU_ERR("Wait for fw shutdown timedout\n");
ret = -ETIMEDOUT;
} else {
ret = 0;
ret = wait_npu_cpc_power_off(npu_dev);
}
load_fw_fail:
@ -333,6 +356,7 @@ int enable_fw(struct npu_device *npu_dev)
static void disable_fw_nolock(struct npu_device *npu_dev)
{
struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;
int ret = 0;
if (!host_ctx->fw_ref_cnt) {
NPU_WARN("fw_ref_cnt is 0\n");
@ -358,10 +382,14 @@ static void disable_fw_nolock(struct npu_device *npu_dev)
msleep(500);
}
if (!host_ctx->auto_pil_disable
&& !wait_for_completion_interruptible_timeout(
&host_ctx->fw_shutdown_done, NW_CMD_TIMEOUT))
NPU_ERR("Wait for fw shutdown timedout\n");
if (!host_ctx->auto_pil_disable) {
ret = wait_for_completion_interruptible_timeout(
&host_ctx->fw_shutdown_done, NW_CMD_TIMEOUT);
if (!ret)
NPU_ERR("Wait for fw shutdown timedout\n");
else
ret = wait_npu_cpc_power_off(npu_dev);
}
npu_disable_irq(npu_dev);
npu_disable_sys_cache(npu_dev);