Loading drivers/media/platform/msm/npu/npu_common.h +1 −1 Original line number Diff line number Diff line Loading @@ -227,6 +227,6 @@ 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 fw_alive); void fw_deinit(struct npu_device *npu_dev, bool fw_alive, bool ssr); #endif /* _NPU_COMMON_H */ drivers/media/platform/msm/npu/npu_debugfs.c +1 −1 Original line number Diff line number Diff line Loading @@ -374,7 +374,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, true); fw_deinit(npu_dev, true, false); } else if (strcmp(buf, "ssr") == 0) { pr_info("trigger error irq\n"); if (npu_enable_core_power(npu_dev)) Loading drivers/media/platform/msm/npu/npu_host_ipc.c +0 −13 Original line number Diff line number Diff line Loading @@ -33,9 +33,6 @@ #define QUEUE_TBL_VERSION 0x87654321 static DEFINE_SPINLOCK(hfi_rd_lock); static DEFINE_SPINLOCK(hfi_wr_lock); /* ------------------------------------------------------------------------- * Data Structures * ------------------------------------------------------------------------- Loading Loading @@ -210,7 +207,6 @@ static int ipc_queue_read(struct npu_device *npu_dev, uint32_t packet_size, new_read_idx; size_t read_ptr; size_t offset = 0; unsigned long flags; offset = (size_t)IPC_ADDR + sizeof(struct hfi_queue_tbl_header) + target_que * sizeof(struct hfi_queue_header); Loading @@ -218,8 +214,6 @@ static int ipc_queue_read(struct npu_device *npu_dev, if ((packet == NULL) || (is_tx_req_set == NULL)) return -EINVAL; spin_lock_irqsave(&hfi_rd_lock, flags); /* Read the queue */ MEMR(npu_dev, (void *)((size_t)offset), (uint8_t *)&queue, HFI_QUEUE_HEADER_SIZE); Loading Loading @@ -294,8 +288,6 @@ static int ipc_queue_read(struct npu_device *npu_dev, (size_t)&(queue.qhdr_read_idx) - (size_t)&queue)), (uint8_t *)&queue.qhdr_read_idx, sizeof(queue.qhdr_read_idx)); spin_unlock_irqrestore(&hfi_rd_lock, flags); return status; } Loading @@ -309,7 +301,6 @@ static int ipc_queue_write(struct npu_device *npu_dev, uint32_t empty_space; void *write_ptr; uint32_t read_idx; unsigned long flags; size_t offset = (size_t)IPC_ADDR + sizeof(struct hfi_queue_tbl_header) + Loading @@ -318,8 +309,6 @@ static int ipc_queue_write(struct npu_device *npu_dev, if ((packet == NULL) || (is_rx_req_set == NULL)) return -EINVAL; spin_lock_irqsave(&hfi_wr_lock, flags); MEMR(npu_dev, (void *)((size_t)offset), (uint8_t *)&queue, HFI_QUEUE_HEADER_SIZE); packet_size = (*(uint32_t *)packet); Loading Loading @@ -395,8 +384,6 @@ static int ipc_queue_write(struct npu_device *npu_dev, (size_t)&(queue.qhdr_write_idx) - (size_t)&queue))), &queue.qhdr_write_idx, sizeof(queue.qhdr_write_idx)); spin_unlock_irqrestore(&hfi_wr_lock, flags); return status; } Loading drivers/media/platform/msm/npu/npu_hw_access.c +2 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ void npu_interrupt_ack(struct npu_device *npu_dev, uint32_t intr_num) if (wdg_irq_sts != 0) { pr_err("wdg irq %x\n", wdg_irq_sts); host_ctx->wdg_irq_sts |= wdg_irq_sts; host_ctx->fw_error = true; } error_irq_sts = REGR(npu_dev, NPU_MASTERn_ERROR_IRQ_STATUS(0)); Loading @@ -129,6 +130,7 @@ void npu_interrupt_ack(struct npu_device *npu_dev, uint32_t intr_num) REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_CLEAR(0), error_irq_sts); pr_err("error irq %x\n", error_irq_sts); host_ctx->err_irq_sts |= error_irq_sts; host_ctx->fw_error = true; } } Loading drivers/media/platform/msm/npu/npu_mgr.c +134 −94 Original line number Diff line number Diff line Loading @@ -53,6 +53,10 @@ static void log_msg_proc(struct npu_device *npu_dev, uint32_t *msg); static void host_session_msg_hdlr(struct npu_device *npu_dev); static void host_session_log_hdlr(struct npu_device *npu_dev); static int host_error_hdlr(struct npu_device *npu_dev); static int npu_send_network_cmd(struct npu_device *npu_dev, struct npu_network *network, void *cmd_ptr); static int npu_send_misc_cmd(struct npu_device *npu_dev, uint32_t q_idx, void *cmd_ptr); /* ------------------------------------------------------------------------- * Function Definitions - Init / Deinit Loading @@ -61,24 +65,15 @@ static int host_error_hdlr(struct npu_device *npu_dev); int fw_init(struct npu_device *npu_dev) { uint32_t reg_val = 0; unsigned long flags; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; spin_lock_irqsave(&host_ctx->lock, flags); mutex_lock(&host_ctx->lock); if (host_ctx->fw_state == FW_ENABLED) { host_ctx->fw_ref_cnt++; spin_unlock_irqrestore(&host_ctx->lock, flags); mutex_unlock(&host_ctx->lock); return 0; } else if (host_ctx->fw_state == FW_ENABLING || host_ctx->fw_state == FW_DISABLING) { spin_unlock_irqrestore(&host_ctx->lock, flags); return -EAGAIN; } host_ctx->fw_state = FW_ENABLING; spin_unlock_irqrestore(&host_ctx->lock, flags); if (npu_enable_core_power(npu_dev)) { ret = -EPERM; goto enable_pw_fail; Loading Loading @@ -148,18 +143,18 @@ int fw_init(struct npu_device *npu_dev) goto wait_fw_ready_fail; } host_ctx->fw_state = FW_ENABLED; host_ctx->fw_error = false; host_ctx->fw_ref_cnt++; mutex_unlock(&host_ctx->lock); pr_debug("firmware init complete\n"); /* Set logging state */ if (!npu_hw_log_enabled()) { pr_debug("fw logging disabled\n"); turn_off_fw_logging(npu_dev); } spin_lock_irqsave(&host_ctx->lock, flags); host_ctx->fw_state = FW_ENABLED; host_ctx->fw_ref_cnt++; spin_unlock_irqrestore(&host_ctx->lock, flags); pr_debug("firmware init complete\n"); return ret; wait_fw_ready_fail: Loading @@ -172,26 +167,33 @@ int fw_init(struct npu_device *npu_dev) npu_disable_core_power(npu_dev); enable_pw_fail: host_ctx->fw_state = FW_DISABLED; mutex_unlock(&host_ctx->lock); return ret; } void fw_deinit(struct npu_device *npu_dev, bool fw_alive) void fw_deinit(struct npu_device *npu_dev, bool fw_alive, bool ssr) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; struct ipc_cmd_shutdown_pkt cmd_shutdown_pkt; unsigned long flags; int ret = 0; struct npu_network *network = NULL; int ret = 0, i; spin_lock_irqsave(&host_ctx->lock, flags); mutex_lock(&host_ctx->lock); if (!ssr && (host_ctx->fw_ref_cnt > 0)) host_ctx->fw_ref_cnt--; pr_debug("fw_ref_cnt %d\n", host_ctx->fw_ref_cnt); if ((host_ctx->fw_state != FW_ENABLED) || (host_ctx->fw_ref_cnt > 0 && fw_alive)) { spin_unlock_irqrestore(&host_ctx->lock, flags); if (host_ctx->fw_state != FW_ENABLED) { pr_err("fw is not enabled\n"); mutex_unlock(&host_ctx->lock); return; } if ((host_ctx->fw_ref_cnt > 0) && !ssr) { mutex_unlock(&host_ctx->lock); return; } host_ctx->fw_state = FW_DISABLING; spin_unlock_irqrestore(&host_ctx->lock, flags); npu_disable_irq(npu_dev); Loading @@ -200,7 +202,8 @@ void fw_deinit(struct npu_device *npu_dev, bool fw_alive) cmd_shutdown_pkt.header.cmd_type = NPU_IPC_CMD_SHUTDOWN; cmd_shutdown_pkt.header.size = sizeof(struct ipc_cmd_shutdown_pkt); cmd_shutdown_pkt.header.trans_id = 1; cmd_shutdown_pkt.header.trans_id = atomic_add_return(1, &host_ctx->ipc_trans_id); cmd_shutdown_pkt.header.flags = 0xF; ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_CMD_HIGH_PRIORITY, &cmd_shutdown_pkt); Loading @@ -226,6 +229,16 @@ void fw_deinit(struct npu_device *npu_dev, bool fw_alive) host_ctx->fw_state = FW_DISABLED; npu_disable_core_power(npu_dev); if (ssr) { /* mark all existing network to error state */ for (i = 0; i < MAX_LOADED_NETWORK; i++) { network = &host_ctx->networks[i]; if (network->is_valid) network->fw_error = true; } } mutex_unlock(&host_ctx->lock); pr_debug("firmware deinit complete\n"); return; } Loading @@ -235,14 +248,9 @@ int npu_host_init(struct npu_device *npu_dev) int sts = 0; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; memset(host_ctx, 0, sizeof(*host_ctx)); init_completion(&host_ctx->loopback_done); host_ctx->sys_cache_disable = 0; spin_lock_init(&host_ctx->lock); host_ctx->fw_state = FW_DISABLED; host_ctx->fw_ref_cnt = 0; host_ctx->exec_flags_override = 0; host_ctx->fw_dbg_mode = 0; mutex_init(&host_ctx->lock); atomic_set(&host_ctx->ipc_trans_id, 1); host_ctx->wq = npu_create_wq(host_ctx, "irq_hdl", host_irq_wq, Loading @@ -258,6 +266,7 @@ void npu_host_deinit(struct npu_device *npu_dev) struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; npu_destroy_wq(host_ctx->wq); mutex_destroy(&host_ctx->lock); } /* ------------------------------------------------------------------------- Loading Loading @@ -299,21 +308,19 @@ static int host_error_hdlr(struct npu_device *npu_dev) fw_alive = false; } fw_deinit(npu_dev, fw_alive); fw_init(npu_dev); fw_deinit(npu_dev, fw_alive, true); host_ctx->wdg_irq_sts = 0; host_ctx->err_irq_sts = 0; /* flush all pending npu cmds with error */ /* flush all pending npu cmds */ for (i = 0; i < MAX_LOADED_NETWORK; i++) { network = &host_ctx->networks[i]; if (network->id != 0) { network->fw_error = true; if (network->is_valid && network->cmd_pending && network->fw_error) { pr_debug("complete network %x\n", network->id); complete(&network->cmd_done); } } complete_all(&host_ctx->loopback_done); return 1; Loading @@ -337,15 +344,17 @@ static void host_irq_wq(struct work_struct *work) static void turn_off_fw_logging(struct npu_device *npu_dev) { struct ipc_cmd_log_state_pkt log_packet; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; log_packet.header.cmd_type = NPU_IPC_CMD_CONFIG_LOG; log_packet.header.size = sizeof(struct ipc_cmd_log_state_pkt); log_packet.header.trans_id = 1; log_packet.header.trans_id = atomic_add_return(1, &host_ctx->ipc_trans_id); log_packet.header.flags = 0xF; log_packet.log_state.module_msk = 0; log_packet.log_state.level_msk = 0; ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_CMD_HIGH_PRIORITY, ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_CMD_HIGH_PRIORITY, &log_packet); pr_debug("NPU_IPC_CMD_CONFIG_LOG sent status: %d\n", ret); Loading Loading @@ -386,9 +395,8 @@ static struct npu_network *alloc_network(struct npu_host_ctx *ctx) { int32_t i; struct npu_network *network = ctx->networks; unsigned long flags; spin_lock_irqsave(&ctx->lock, flags); mutex_lock(&ctx->lock); for (i = 0; i < MAX_LOADED_NETWORK; i++) { if (network->id == 0) { network->id = i + 1; Loading @@ -401,12 +409,13 @@ static struct npu_network *alloc_network(struct npu_host_ctx *ctx) network = NULL; else ctx->network_num++; spin_unlock_irqrestore(&ctx->lock, flags); mutex_unlock(&ctx->lock); if (network) { init_completion(&network->cmd_done); network->is_valid = true; network->fw_error = false; network->cmd_pending = false; } return network; Loading Loading @@ -447,13 +456,12 @@ static struct npu_network *get_network_by_id(struct npu_host_ctx *ctx, static void free_network(struct npu_host_ctx *ctx, int64_t id) { struct npu_network *network = get_network_by_id(ctx, id); unsigned long flags; if (network) { spin_lock_irqsave(&ctx->lock, flags); mutex_lock(&ctx->lock); memset(network, 0, sizeof(struct npu_network)); ctx->network_num--; spin_unlock_irqrestore(&ctx->lock, flags); mutex_unlock(&ctx->lock); } } Loading Loading @@ -492,7 +500,7 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) exe_rsp_pkt->network_hdl); break; } network->cmd_pending = false; complete(&network->cmd_done); break; } Loading Loading @@ -524,6 +532,7 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) memcpy(network->stats_buf, exe_rsp_pkt->stats_data, stats_size); network->cmd_pending = false; complete(&network->cmd_done); break; } Loading @@ -549,6 +558,7 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) break; } network->network_hdl = load_rsp_pkt->network_hdl; network->cmd_pending = false; complete(&network->cmd_done); break; } Loading @@ -569,6 +579,7 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) break; } network->cmd_pending = false; complete(&network->cmd_done); break; } Loading Loading @@ -667,6 +678,50 @@ int32_t npu_host_unmap_buf(struct npu_device *npu_dev, return 0; } static int npu_send_network_cmd(struct npu_device *npu_dev, struct npu_network *network, void *cmd_ptr) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; mutex_lock(&host_ctx->lock); if (network->fw_error || host_ctx->fw_error || (host_ctx->fw_state == FW_DISABLED)) { pr_err("fw is in error state or disabled, can't send network cmd\n"); ret = -EIO; } else { pr_debug("Send cmd %d\n", ((struct ipc_cmd_header_pkt *)cmd_ptr)->cmd_type); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, cmd_ptr); if (!ret) network->cmd_pending = true; } mutex_unlock(&host_ctx->lock); return ret; } static int npu_send_misc_cmd(struct npu_device *npu_dev, uint32_t q_idx, void *cmd_ptr) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; mutex_lock(&host_ctx->lock); if (host_ctx->fw_error || (host_ctx->fw_state == FW_DISABLED)) { pr_err("fw is in error state or disabled, can't send misc cmd\n"); ret = -EIO; } else { pr_debug("Send cmd %d\n", ((struct ipc_cmd_header_pkt *)cmd_ptr)->cmd_type); ret = npu_host_ipc_send_cmd(npu_dev, q_idx, cmd_ptr); } mutex_unlock(&host_ctx->lock); return ret; } static void host_copy_patch_data(struct npu_patch_tuple *param, uint32_t value, struct msm_npu_layer *layer_info) { Loading Loading @@ -775,13 +830,9 @@ int32_t npu_host_load_network(struct npu_device *npu_dev, /* NPU_IPC_CMD_LOAD will go onto IPC_QUEUE_APPS_EXEC */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &load_packet); pr_debug("NPU_IPC_CMD_LOAD sent status: %d\n", ret); ret = npu_send_network_cmd(npu_dev, network, &load_packet); if (ret) { ret = -EIO; pr_err("NPU_IPC_CMD_LOAD sent failed: %d\n", ret); goto error_free_network; } Loading @@ -805,7 +856,7 @@ int32_t npu_host_load_network(struct npu_device *npu_dev, error_free_network: free_network(host_ctx, network->id); err_deinit_fw: fw_deinit(npu_dev, true); fw_deinit(npu_dev, true, false); return ret; } Loading Loading @@ -875,13 +926,9 @@ int32_t npu_host_load_network_v2(struct npu_device *npu_dev, /* NPU_IPC_CMD_LOAD_V2 will go onto IPC_QUEUE_APPS_EXEC */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, load_packet); pr_debug("NPU_IPC_CMD_LOAD_V2 sent status: %d\n", ret); ret = npu_send_network_cmd(npu_dev, network, load_packet); if (ret) { ret = -EIO; pr_debug("NPU_IPC_CMD_LOAD_V2 sent failed: %d\n", ret); goto error_free_network; } Loading @@ -906,7 +953,7 @@ int32_t npu_host_load_network_v2(struct npu_device *npu_dev, kfree(load_packet); free_network(host_ctx, network->id); err_deinit_fw: fw_deinit(npu_dev, true); fw_deinit(npu_dev, true, false); return ret; } Loading Loading @@ -938,15 +985,12 @@ int32_t npu_host_unload_network(struct npu_device *npu_dev, /* NPU_IPC_CMD_UNLOAD will go onto IPC_QUEUE_APPS_EXEC */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &unload_packet); ret = npu_send_network_cmd(npu_dev, network, &unload_packet); if (ret) { pr_err("NPU_IPC_CMD_UNLOAD sent failed: %d\n", ret); return -EIO; } if (!wait_for_completion_interruptible_timeout(&network->cmd_done, } else if (!wait_for_completion_interruptible_timeout( &network->cmd_done, (host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ? NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT)) { pr_err_ratelimited("npu: NPU_IPC_CMD_UNLOAD time out\n"); Loading @@ -962,8 +1006,7 @@ int32_t npu_host_unload_network(struct npu_device *npu_dev, * handle is unloaded on the firmware side */ free_network(host_ctx, network->id); fw_deinit(npu_dev, true); fw_deinit(npu_dev, true, false); return ret; } Loading Loading @@ -1014,11 +1057,11 @@ int32_t npu_host_exec_network(struct npu_device *npu_dev, /* Send it on the high priority queue */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &exec_packet); pr_debug("NPU_IPC_CMD_EXECUTE sent status: %d\n", ret); ret = npu_send_network_cmd(npu_dev, network, &exec_packet); if (!wait_for_completion_interruptible_timeout( if (ret) { pr_err("NPU_IPC_CMD_EXECUTE sent failed: %d\n", ret); } else if (!wait_for_completion_interruptible_timeout( &network->cmd_done, (host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ? NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT)) { Loading @@ -1029,8 +1072,7 @@ int32_t npu_host_exec_network(struct npu_device *npu_dev, } else if (network->fw_error) { ret = -EIO; pr_err("execute cmd returns with error\n"); } } else { /* Invalidate output buffers */ for (i = 0; i < exec_ioctl->output_layer_num; i++) { if (exec_ioctl->output_layer_num == 1) { Loading @@ -1038,6 +1080,7 @@ int32_t npu_host_exec_network(struct npu_device *npu_dev, exec_ioctl->output_layers[i].buf_hdl); } } } return ret; } Loading Loading @@ -1100,11 +1143,11 @@ int32_t npu_host_exec_network_v2(struct npu_device *npu_dev, /* Send it on the high priority queue */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, exec_packet); pr_debug("NPU_IPC_CMD_EXECUTE_V2 sent status: %d\n", ret); ret = npu_send_network_cmd(npu_dev, network, exec_packet); if (!wait_for_completion_interruptible_timeout( if (ret) { pr_err("NPU_IPC_CMD_EXECUTE_V2 sent failed: %d\n", ret); } else if (!wait_for_completion_interruptible_timeout( &network->cmd_done, (host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ? NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT)) { Loading @@ -1115,9 +1158,7 @@ int32_t npu_host_exec_network_v2(struct npu_device *npu_dev, } else if (network->fw_error) { ret = -EIO; pr_err("execute cmd returns with error\n"); } if (!ret) { } else { exec_ioctl->stats_buf_size = network->stats_buf_size; if (exec_ioctl->stats_buf_size) { if (copy_to_user( Loading Loading @@ -1150,8 +1191,7 @@ int32_t npu_host_loopback_test(struct npu_device *npu_dev) loopback_packet.loopbackParams = 15; reinit_completion(&host_ctx->loopback_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &loopback_packet); ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &loopback_packet); if (ret) { pr_err("NPU_IPC_CMD_LOOPBACK sent failed: %d\n", ret); Loading @@ -1163,7 +1203,7 @@ int32_t npu_host_loopback_test(struct npu_device *npu_dev) ret = -ETIMEDOUT; } fw_deinit(npu_dev, true); fw_deinit(npu_dev, true, false); return ret; } Loading
drivers/media/platform/msm/npu/npu_common.h +1 −1 Original line number Diff line number Diff line Loading @@ -227,6 +227,6 @@ 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 fw_alive); void fw_deinit(struct npu_device *npu_dev, bool fw_alive, bool ssr); #endif /* _NPU_COMMON_H */
drivers/media/platform/msm/npu/npu_debugfs.c +1 −1 Original line number Diff line number Diff line Loading @@ -374,7 +374,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, true); fw_deinit(npu_dev, true, false); } else if (strcmp(buf, "ssr") == 0) { pr_info("trigger error irq\n"); if (npu_enable_core_power(npu_dev)) Loading
drivers/media/platform/msm/npu/npu_host_ipc.c +0 −13 Original line number Diff line number Diff line Loading @@ -33,9 +33,6 @@ #define QUEUE_TBL_VERSION 0x87654321 static DEFINE_SPINLOCK(hfi_rd_lock); static DEFINE_SPINLOCK(hfi_wr_lock); /* ------------------------------------------------------------------------- * Data Structures * ------------------------------------------------------------------------- Loading Loading @@ -210,7 +207,6 @@ static int ipc_queue_read(struct npu_device *npu_dev, uint32_t packet_size, new_read_idx; size_t read_ptr; size_t offset = 0; unsigned long flags; offset = (size_t)IPC_ADDR + sizeof(struct hfi_queue_tbl_header) + target_que * sizeof(struct hfi_queue_header); Loading @@ -218,8 +214,6 @@ static int ipc_queue_read(struct npu_device *npu_dev, if ((packet == NULL) || (is_tx_req_set == NULL)) return -EINVAL; spin_lock_irqsave(&hfi_rd_lock, flags); /* Read the queue */ MEMR(npu_dev, (void *)((size_t)offset), (uint8_t *)&queue, HFI_QUEUE_HEADER_SIZE); Loading Loading @@ -294,8 +288,6 @@ static int ipc_queue_read(struct npu_device *npu_dev, (size_t)&(queue.qhdr_read_idx) - (size_t)&queue)), (uint8_t *)&queue.qhdr_read_idx, sizeof(queue.qhdr_read_idx)); spin_unlock_irqrestore(&hfi_rd_lock, flags); return status; } Loading @@ -309,7 +301,6 @@ static int ipc_queue_write(struct npu_device *npu_dev, uint32_t empty_space; void *write_ptr; uint32_t read_idx; unsigned long flags; size_t offset = (size_t)IPC_ADDR + sizeof(struct hfi_queue_tbl_header) + Loading @@ -318,8 +309,6 @@ static int ipc_queue_write(struct npu_device *npu_dev, if ((packet == NULL) || (is_rx_req_set == NULL)) return -EINVAL; spin_lock_irqsave(&hfi_wr_lock, flags); MEMR(npu_dev, (void *)((size_t)offset), (uint8_t *)&queue, HFI_QUEUE_HEADER_SIZE); packet_size = (*(uint32_t *)packet); Loading Loading @@ -395,8 +384,6 @@ static int ipc_queue_write(struct npu_device *npu_dev, (size_t)&(queue.qhdr_write_idx) - (size_t)&queue))), &queue.qhdr_write_idx, sizeof(queue.qhdr_write_idx)); spin_unlock_irqrestore(&hfi_wr_lock, flags); return status; } Loading
drivers/media/platform/msm/npu/npu_hw_access.c +2 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ void npu_interrupt_ack(struct npu_device *npu_dev, uint32_t intr_num) if (wdg_irq_sts != 0) { pr_err("wdg irq %x\n", wdg_irq_sts); host_ctx->wdg_irq_sts |= wdg_irq_sts; host_ctx->fw_error = true; } error_irq_sts = REGR(npu_dev, NPU_MASTERn_ERROR_IRQ_STATUS(0)); Loading @@ -129,6 +130,7 @@ void npu_interrupt_ack(struct npu_device *npu_dev, uint32_t intr_num) REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_CLEAR(0), error_irq_sts); pr_err("error irq %x\n", error_irq_sts); host_ctx->err_irq_sts |= error_irq_sts; host_ctx->fw_error = true; } } Loading
drivers/media/platform/msm/npu/npu_mgr.c +134 −94 Original line number Diff line number Diff line Loading @@ -53,6 +53,10 @@ static void log_msg_proc(struct npu_device *npu_dev, uint32_t *msg); static void host_session_msg_hdlr(struct npu_device *npu_dev); static void host_session_log_hdlr(struct npu_device *npu_dev); static int host_error_hdlr(struct npu_device *npu_dev); static int npu_send_network_cmd(struct npu_device *npu_dev, struct npu_network *network, void *cmd_ptr); static int npu_send_misc_cmd(struct npu_device *npu_dev, uint32_t q_idx, void *cmd_ptr); /* ------------------------------------------------------------------------- * Function Definitions - Init / Deinit Loading @@ -61,24 +65,15 @@ static int host_error_hdlr(struct npu_device *npu_dev); int fw_init(struct npu_device *npu_dev) { uint32_t reg_val = 0; unsigned long flags; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; spin_lock_irqsave(&host_ctx->lock, flags); mutex_lock(&host_ctx->lock); if (host_ctx->fw_state == FW_ENABLED) { host_ctx->fw_ref_cnt++; spin_unlock_irqrestore(&host_ctx->lock, flags); mutex_unlock(&host_ctx->lock); return 0; } else if (host_ctx->fw_state == FW_ENABLING || host_ctx->fw_state == FW_DISABLING) { spin_unlock_irqrestore(&host_ctx->lock, flags); return -EAGAIN; } host_ctx->fw_state = FW_ENABLING; spin_unlock_irqrestore(&host_ctx->lock, flags); if (npu_enable_core_power(npu_dev)) { ret = -EPERM; goto enable_pw_fail; Loading Loading @@ -148,18 +143,18 @@ int fw_init(struct npu_device *npu_dev) goto wait_fw_ready_fail; } host_ctx->fw_state = FW_ENABLED; host_ctx->fw_error = false; host_ctx->fw_ref_cnt++; mutex_unlock(&host_ctx->lock); pr_debug("firmware init complete\n"); /* Set logging state */ if (!npu_hw_log_enabled()) { pr_debug("fw logging disabled\n"); turn_off_fw_logging(npu_dev); } spin_lock_irqsave(&host_ctx->lock, flags); host_ctx->fw_state = FW_ENABLED; host_ctx->fw_ref_cnt++; spin_unlock_irqrestore(&host_ctx->lock, flags); pr_debug("firmware init complete\n"); return ret; wait_fw_ready_fail: Loading @@ -172,26 +167,33 @@ int fw_init(struct npu_device *npu_dev) npu_disable_core_power(npu_dev); enable_pw_fail: host_ctx->fw_state = FW_DISABLED; mutex_unlock(&host_ctx->lock); return ret; } void fw_deinit(struct npu_device *npu_dev, bool fw_alive) void fw_deinit(struct npu_device *npu_dev, bool fw_alive, bool ssr) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; struct ipc_cmd_shutdown_pkt cmd_shutdown_pkt; unsigned long flags; int ret = 0; struct npu_network *network = NULL; int ret = 0, i; spin_lock_irqsave(&host_ctx->lock, flags); mutex_lock(&host_ctx->lock); if (!ssr && (host_ctx->fw_ref_cnt > 0)) host_ctx->fw_ref_cnt--; pr_debug("fw_ref_cnt %d\n", host_ctx->fw_ref_cnt); if ((host_ctx->fw_state != FW_ENABLED) || (host_ctx->fw_ref_cnt > 0 && fw_alive)) { spin_unlock_irqrestore(&host_ctx->lock, flags); if (host_ctx->fw_state != FW_ENABLED) { pr_err("fw is not enabled\n"); mutex_unlock(&host_ctx->lock); return; } if ((host_ctx->fw_ref_cnt > 0) && !ssr) { mutex_unlock(&host_ctx->lock); return; } host_ctx->fw_state = FW_DISABLING; spin_unlock_irqrestore(&host_ctx->lock, flags); npu_disable_irq(npu_dev); Loading @@ -200,7 +202,8 @@ void fw_deinit(struct npu_device *npu_dev, bool fw_alive) cmd_shutdown_pkt.header.cmd_type = NPU_IPC_CMD_SHUTDOWN; cmd_shutdown_pkt.header.size = sizeof(struct ipc_cmd_shutdown_pkt); cmd_shutdown_pkt.header.trans_id = 1; cmd_shutdown_pkt.header.trans_id = atomic_add_return(1, &host_ctx->ipc_trans_id); cmd_shutdown_pkt.header.flags = 0xF; ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_CMD_HIGH_PRIORITY, &cmd_shutdown_pkt); Loading @@ -226,6 +229,16 @@ void fw_deinit(struct npu_device *npu_dev, bool fw_alive) host_ctx->fw_state = FW_DISABLED; npu_disable_core_power(npu_dev); if (ssr) { /* mark all existing network to error state */ for (i = 0; i < MAX_LOADED_NETWORK; i++) { network = &host_ctx->networks[i]; if (network->is_valid) network->fw_error = true; } } mutex_unlock(&host_ctx->lock); pr_debug("firmware deinit complete\n"); return; } Loading @@ -235,14 +248,9 @@ int npu_host_init(struct npu_device *npu_dev) int sts = 0; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; memset(host_ctx, 0, sizeof(*host_ctx)); init_completion(&host_ctx->loopback_done); host_ctx->sys_cache_disable = 0; spin_lock_init(&host_ctx->lock); host_ctx->fw_state = FW_DISABLED; host_ctx->fw_ref_cnt = 0; host_ctx->exec_flags_override = 0; host_ctx->fw_dbg_mode = 0; mutex_init(&host_ctx->lock); atomic_set(&host_ctx->ipc_trans_id, 1); host_ctx->wq = npu_create_wq(host_ctx, "irq_hdl", host_irq_wq, Loading @@ -258,6 +266,7 @@ void npu_host_deinit(struct npu_device *npu_dev) struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; npu_destroy_wq(host_ctx->wq); mutex_destroy(&host_ctx->lock); } /* ------------------------------------------------------------------------- Loading Loading @@ -299,21 +308,19 @@ static int host_error_hdlr(struct npu_device *npu_dev) fw_alive = false; } fw_deinit(npu_dev, fw_alive); fw_init(npu_dev); fw_deinit(npu_dev, fw_alive, true); host_ctx->wdg_irq_sts = 0; host_ctx->err_irq_sts = 0; /* flush all pending npu cmds with error */ /* flush all pending npu cmds */ for (i = 0; i < MAX_LOADED_NETWORK; i++) { network = &host_ctx->networks[i]; if (network->id != 0) { network->fw_error = true; if (network->is_valid && network->cmd_pending && network->fw_error) { pr_debug("complete network %x\n", network->id); complete(&network->cmd_done); } } complete_all(&host_ctx->loopback_done); return 1; Loading @@ -337,15 +344,17 @@ static void host_irq_wq(struct work_struct *work) static void turn_off_fw_logging(struct npu_device *npu_dev) { struct ipc_cmd_log_state_pkt log_packet; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; log_packet.header.cmd_type = NPU_IPC_CMD_CONFIG_LOG; log_packet.header.size = sizeof(struct ipc_cmd_log_state_pkt); log_packet.header.trans_id = 1; log_packet.header.trans_id = atomic_add_return(1, &host_ctx->ipc_trans_id); log_packet.header.flags = 0xF; log_packet.log_state.module_msk = 0; log_packet.log_state.level_msk = 0; ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_CMD_HIGH_PRIORITY, ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_CMD_HIGH_PRIORITY, &log_packet); pr_debug("NPU_IPC_CMD_CONFIG_LOG sent status: %d\n", ret); Loading Loading @@ -386,9 +395,8 @@ static struct npu_network *alloc_network(struct npu_host_ctx *ctx) { int32_t i; struct npu_network *network = ctx->networks; unsigned long flags; spin_lock_irqsave(&ctx->lock, flags); mutex_lock(&ctx->lock); for (i = 0; i < MAX_LOADED_NETWORK; i++) { if (network->id == 0) { network->id = i + 1; Loading @@ -401,12 +409,13 @@ static struct npu_network *alloc_network(struct npu_host_ctx *ctx) network = NULL; else ctx->network_num++; spin_unlock_irqrestore(&ctx->lock, flags); mutex_unlock(&ctx->lock); if (network) { init_completion(&network->cmd_done); network->is_valid = true; network->fw_error = false; network->cmd_pending = false; } return network; Loading Loading @@ -447,13 +456,12 @@ static struct npu_network *get_network_by_id(struct npu_host_ctx *ctx, static void free_network(struct npu_host_ctx *ctx, int64_t id) { struct npu_network *network = get_network_by_id(ctx, id); unsigned long flags; if (network) { spin_lock_irqsave(&ctx->lock, flags); mutex_lock(&ctx->lock); memset(network, 0, sizeof(struct npu_network)); ctx->network_num--; spin_unlock_irqrestore(&ctx->lock, flags); mutex_unlock(&ctx->lock); } } Loading Loading @@ -492,7 +500,7 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) exe_rsp_pkt->network_hdl); break; } network->cmd_pending = false; complete(&network->cmd_done); break; } Loading Loading @@ -524,6 +532,7 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) memcpy(network->stats_buf, exe_rsp_pkt->stats_data, stats_size); network->cmd_pending = false; complete(&network->cmd_done); break; } Loading @@ -549,6 +558,7 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) break; } network->network_hdl = load_rsp_pkt->network_hdl; network->cmd_pending = false; complete(&network->cmd_done); break; } Loading @@ -569,6 +579,7 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg) break; } network->cmd_pending = false; complete(&network->cmd_done); break; } Loading Loading @@ -667,6 +678,50 @@ int32_t npu_host_unmap_buf(struct npu_device *npu_dev, return 0; } static int npu_send_network_cmd(struct npu_device *npu_dev, struct npu_network *network, void *cmd_ptr) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; mutex_lock(&host_ctx->lock); if (network->fw_error || host_ctx->fw_error || (host_ctx->fw_state == FW_DISABLED)) { pr_err("fw is in error state or disabled, can't send network cmd\n"); ret = -EIO; } else { pr_debug("Send cmd %d\n", ((struct ipc_cmd_header_pkt *)cmd_ptr)->cmd_type); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, cmd_ptr); if (!ret) network->cmd_pending = true; } mutex_unlock(&host_ctx->lock); return ret; } static int npu_send_misc_cmd(struct npu_device *npu_dev, uint32_t q_idx, void *cmd_ptr) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; mutex_lock(&host_ctx->lock); if (host_ctx->fw_error || (host_ctx->fw_state == FW_DISABLED)) { pr_err("fw is in error state or disabled, can't send misc cmd\n"); ret = -EIO; } else { pr_debug("Send cmd %d\n", ((struct ipc_cmd_header_pkt *)cmd_ptr)->cmd_type); ret = npu_host_ipc_send_cmd(npu_dev, q_idx, cmd_ptr); } mutex_unlock(&host_ctx->lock); return ret; } static void host_copy_patch_data(struct npu_patch_tuple *param, uint32_t value, struct msm_npu_layer *layer_info) { Loading Loading @@ -775,13 +830,9 @@ int32_t npu_host_load_network(struct npu_device *npu_dev, /* NPU_IPC_CMD_LOAD will go onto IPC_QUEUE_APPS_EXEC */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &load_packet); pr_debug("NPU_IPC_CMD_LOAD sent status: %d\n", ret); ret = npu_send_network_cmd(npu_dev, network, &load_packet); if (ret) { ret = -EIO; pr_err("NPU_IPC_CMD_LOAD sent failed: %d\n", ret); goto error_free_network; } Loading @@ -805,7 +856,7 @@ int32_t npu_host_load_network(struct npu_device *npu_dev, error_free_network: free_network(host_ctx, network->id); err_deinit_fw: fw_deinit(npu_dev, true); fw_deinit(npu_dev, true, false); return ret; } Loading Loading @@ -875,13 +926,9 @@ int32_t npu_host_load_network_v2(struct npu_device *npu_dev, /* NPU_IPC_CMD_LOAD_V2 will go onto IPC_QUEUE_APPS_EXEC */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, load_packet); pr_debug("NPU_IPC_CMD_LOAD_V2 sent status: %d\n", ret); ret = npu_send_network_cmd(npu_dev, network, load_packet); if (ret) { ret = -EIO; pr_debug("NPU_IPC_CMD_LOAD_V2 sent failed: %d\n", ret); goto error_free_network; } Loading @@ -906,7 +953,7 @@ int32_t npu_host_load_network_v2(struct npu_device *npu_dev, kfree(load_packet); free_network(host_ctx, network->id); err_deinit_fw: fw_deinit(npu_dev, true); fw_deinit(npu_dev, true, false); return ret; } Loading Loading @@ -938,15 +985,12 @@ int32_t npu_host_unload_network(struct npu_device *npu_dev, /* NPU_IPC_CMD_UNLOAD will go onto IPC_QUEUE_APPS_EXEC */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &unload_packet); ret = npu_send_network_cmd(npu_dev, network, &unload_packet); if (ret) { pr_err("NPU_IPC_CMD_UNLOAD sent failed: %d\n", ret); return -EIO; } if (!wait_for_completion_interruptible_timeout(&network->cmd_done, } else if (!wait_for_completion_interruptible_timeout( &network->cmd_done, (host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ? NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT)) { pr_err_ratelimited("npu: NPU_IPC_CMD_UNLOAD time out\n"); Loading @@ -962,8 +1006,7 @@ int32_t npu_host_unload_network(struct npu_device *npu_dev, * handle is unloaded on the firmware side */ free_network(host_ctx, network->id); fw_deinit(npu_dev, true); fw_deinit(npu_dev, true, false); return ret; } Loading Loading @@ -1014,11 +1057,11 @@ int32_t npu_host_exec_network(struct npu_device *npu_dev, /* Send it on the high priority queue */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &exec_packet); pr_debug("NPU_IPC_CMD_EXECUTE sent status: %d\n", ret); ret = npu_send_network_cmd(npu_dev, network, &exec_packet); if (!wait_for_completion_interruptible_timeout( if (ret) { pr_err("NPU_IPC_CMD_EXECUTE sent failed: %d\n", ret); } else if (!wait_for_completion_interruptible_timeout( &network->cmd_done, (host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ? NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT)) { Loading @@ -1029,8 +1072,7 @@ int32_t npu_host_exec_network(struct npu_device *npu_dev, } else if (network->fw_error) { ret = -EIO; pr_err("execute cmd returns with error\n"); } } else { /* Invalidate output buffers */ for (i = 0; i < exec_ioctl->output_layer_num; i++) { if (exec_ioctl->output_layer_num == 1) { Loading @@ -1038,6 +1080,7 @@ int32_t npu_host_exec_network(struct npu_device *npu_dev, exec_ioctl->output_layers[i].buf_hdl); } } } return ret; } Loading Loading @@ -1100,11 +1143,11 @@ int32_t npu_host_exec_network_v2(struct npu_device *npu_dev, /* Send it on the high priority queue */ reinit_completion(&network->cmd_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, exec_packet); pr_debug("NPU_IPC_CMD_EXECUTE_V2 sent status: %d\n", ret); ret = npu_send_network_cmd(npu_dev, network, exec_packet); if (!wait_for_completion_interruptible_timeout( if (ret) { pr_err("NPU_IPC_CMD_EXECUTE_V2 sent failed: %d\n", ret); } else if (!wait_for_completion_interruptible_timeout( &network->cmd_done, (host_ctx->fw_dbg_mode & FW_DBG_MODE_INC_TIMEOUT) ? NW_DEBUG_TIMEOUT : NW_CMD_TIMEOUT)) { Loading @@ -1115,9 +1158,7 @@ int32_t npu_host_exec_network_v2(struct npu_device *npu_dev, } else if (network->fw_error) { ret = -EIO; pr_err("execute cmd returns with error\n"); } if (!ret) { } else { exec_ioctl->stats_buf_size = network->stats_buf_size; if (exec_ioctl->stats_buf_size) { if (copy_to_user( Loading Loading @@ -1150,8 +1191,7 @@ int32_t npu_host_loopback_test(struct npu_device *npu_dev) loopback_packet.loopbackParams = 15; reinit_completion(&host_ctx->loopback_done); ret = npu_host_ipc_send_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &loopback_packet); ret = npu_send_misc_cmd(npu_dev, IPC_QUEUE_APPS_EXEC, &loopback_packet); if (ret) { pr_err("NPU_IPC_CMD_LOOPBACK sent failed: %d\n", ret); Loading @@ -1163,7 +1203,7 @@ int32_t npu_host_loopback_test(struct npu_device *npu_dev) ret = -ETIMEDOUT; } fw_deinit(npu_dev, true); fw_deinit(npu_dev, true, false); return ret; }