Loading drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c +15 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,20 @@ static int __cam_jpeg_ctx_handle_buf_done_in_acquired(void *ctx, return cam_context_buf_done_from_hw(ctx, done, evt_id); } static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx, struct cam_start_stop_dev_cmd *cmd) { int rc; rc = cam_context_stop_dev_to_hw(ctx); if (rc) { CAM_ERR(CAM_JPEG, "Failed in Stop dev, rc=%d", rc); return rc; } return rc; } /* top state machine */ static struct cam_ctx_ops cam_jpeg_ctx_state_machine[CAM_CTX_STATE_MAX] = { Loading @@ -85,6 +99,7 @@ static struct cam_ctx_ops .ioctl_ops = { .release_dev = __cam_jpeg_ctx_release_dev_in_acquired, .config_dev = __cam_jpeg_ctx_config_dev_in_acquired, .stop_dev = __cam_jpeg_ctx_stop_dev_in_acquired, }, .crm_ops = { }, .irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired, Loading drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +104 −6 Original line number Diff line number Diff line Loading @@ -80,11 +80,23 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) dev_type = ctx_data->jpeg_dev_acquire_info.dev_type; mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex); p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; if (hw_mgr->device_in_use[dev_type][0] == false || p_cfg_req == NULL) { CAM_ERR(CAM_JPEG, "irq for old request %d", rc); mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); return -EINVAL; } irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb; irq_cb.data = NULL; irq_cb.b_set_cb = false; if (!hw_mgr->devices[dev_type][0]->hw_ops.process_cmd) { CAM_ERR(CAM_JPEG, "process_cmd null "); mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); return -EINVAL; } rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd( Loading @@ -93,6 +105,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) &irq_cb, sizeof(irq_cb)); if (rc) { CAM_ERR(CAM_JPEG, "CMD_SET_IRQ_CB failed %d", rc); mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); return rc; } Loading @@ -103,9 +116,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) CAM_ERR(CAM_JPEG, "Failed to Deinit %d HW", dev_type); } mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex); hw_mgr->device_in_use[dev_type][0] = false; p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL; mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); Loading Loading @@ -167,7 +178,6 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) list_add_tail(&p_cfg_req->list, &hw_mgr->free_req_list); return rc; } Loading Loading @@ -319,8 +329,11 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) return -EINVAL; } mutex_lock(&hw_mgr->hw_mgr_mutex); if (list_empty(&hw_mgr->hw_config_req_list)) { CAM_DBG(CAM_JPEG, "no available request"); mutex_unlock(&hw_mgr->hw_mgr_mutex); rc = -EFAULT; goto end; } Loading @@ -329,11 +342,11 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) struct cam_jpeg_hw_cfg_req, list); if (!p_cfg_req) { CAM_ERR(CAM_JPEG, "no request"); mutex_unlock(&hw_mgr->hw_mgr_mutex); rc = -EFAULT; goto end; } mutex_lock(&hw_mgr->hw_mgr_mutex); if (false == hw_mgr->device_in_use[p_cfg_req->dev_type][0]) { hw_mgr->device_in_use[p_cfg_req->dev_type][0] = true; hw_mgr->dev_hw_cfg_args[p_cfg_req->dev_type][0] = p_cfg_req; Loading @@ -344,6 +357,7 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) rc = -EFAULT; goto end; } mutex_unlock(&hw_mgr->hw_mgr_mutex); config_args = (struct cam_hw_config_args *)&p_cfg_req->hw_cfg_args; Loading Loading @@ -464,7 +478,7 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0); if (rc) { CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", CAM_ERR(CAM_JPEG, "Failed to start hw %d", rc); goto end_callcb; } Loading Loading @@ -553,12 +567,12 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) goto err_after_dq_free_list; } mutex_unlock(&hw_mgr->hw_mgr_mutex); task_data = (struct cam_jpeg_process_frame_work_data_t *) task->payload; if (!task_data) { CAM_ERR(CAM_JPEG, "task_data is NULL"); mutex_unlock(&hw_mgr->hw_mgr_mutex); rc = -EINVAL; goto err_after_dq_free_list; } Loading @@ -567,6 +581,7 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) p_cfg_req->hw_cfg_args.num_hw_update_entries); list_add_tail(&p_cfg_req->list, &hw_mgr->hw_config_req_list); mutex_unlock(&hw_mgr->hw_mgr_mutex); task_data->data = (void *)(int64_t)p_cfg_req->dev_type; task_data->request_id = request_id; Loading Loading @@ -719,6 +734,88 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, return rc; } static int cam_jpeg_mgr_flush(void *hw_mgr_priv, struct cam_jpeg_hw_ctx_data *ctx_data) { int rc = 0; struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv; uint32_t dev_type; struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL; struct cam_jpeg_hw_cfg_req *cfg_req, *req_temp; if (!hw_mgr || !ctx_data) { CAM_ERR(CAM_JPEG, "Invalid args"); return -EINVAL; } dev_type = ctx_data->jpeg_dev_acquire_info.dev_type; p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; if (hw_mgr->device_in_use[dev_type][0] == true && p_cfg_req != NULL) { if ((struct cam_jpeg_hw_ctx_data *)p_cfg_req-> hw_cfg_args.ctxt_to_hw_map == ctx_data) { /* stop reset Unregister CB and deinit */ if (hw_mgr->devices[dev_type][0]->hw_ops.stop) { rc = hw_mgr->devices[dev_type][0]->hw_ops.stop( hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0); if (rc) CAM_ERR(CAM_JPEG, "stop fail %d", rc); } else { CAM_ERR(CAM_JPEG, "op stop null "); rc = -EINVAL; } } hw_mgr->device_in_use[dev_type][0] = false; p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL; } list_for_each_entry_safe(cfg_req, req_temp, &hw_mgr->hw_config_req_list, list) { if ((struct cam_jpeg_hw_ctx_data *)cfg_req-> hw_cfg_args.ctxt_to_hw_map != ctx_data) continue; CAM_INFO(CAM_JPEG, "deleting req %pK", cfg_req); list_del_init(&cfg_req->list); } return rc; } static int cam_jpeg_mgr_hw_stop(void *hw_mgr_priv, void *stop_hw_args) { int rc; struct cam_hw_stop_args *stop_args = (struct cam_hw_stop_args *)stop_hw_args; struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv; struct cam_jpeg_hw_ctx_data *ctx_data = NULL; if (!hw_mgr || !stop_args || !stop_args->ctxt_to_hw_map) { CAM_ERR(CAM_JPEG, "Invalid args"); return -EINVAL; } mutex_lock(&hw_mgr->hw_mgr_mutex); ctx_data = (struct cam_jpeg_hw_ctx_data *)stop_args->ctxt_to_hw_map; if (!ctx_data->in_use) { CAM_ERR(CAM_JPEG, "ctx is not in use"); mutex_unlock(&hw_mgr->hw_mgr_mutex); return -EINVAL; } rc = cam_jpeg_mgr_flush(hw_mgr_priv, ctx_data); if ((rc)) CAM_ERR(CAM_JPEG, "flush failed %d", rc); mutex_unlock(&hw_mgr->hw_mgr_mutex); return rc; } static int cam_jpeg_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args) { int rc; Loading Loading @@ -1184,6 +1281,7 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl) hw_mgr_intf->hw_release = cam_jpeg_mgr_release_hw; hw_mgr_intf->hw_prepare_update = cam_jpeg_mgr_prepare_hw_update; hw_mgr_intf->hw_config = cam_jpeg_mgr_config_hw; hw_mgr_intf->hw_stop = cam_jpeg_mgr_hw_stop; mutex_init(&g_jpeg_hw_mgr.hw_mgr_mutex); spin_lock_init(&g_jpeg_hw_mgr.hw_mgr_lock); Loading drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_hw_info_ver_4_2_0.h +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ #define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000 #define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a #define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK 0x8000000 #define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_SHIFT 0x0000001b #define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800 #define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b Loading Loading @@ -63,11 +66,13 @@ static struct cam_jpeg_enc_device_hw_info cam_jpeg_enc_hw_info = { .int_mask_enable_all = 0xFFFFFFFF, .hw_cmd_start = 0x00000001, .reset_cmd = 0x00032093, .hw_cmd_stop = 0x00000002, }, .int_status = { .framedone = CAM_JPEG_HW_MASK_COMP_FRAMEDONE, .resetdone = CAM_JPEG_HW_MASK_COMP_RESET_ACK, .iserror = CAM_JPEG_HW_MASK_COMP_ERR, .stopdone = CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK, } }; Loading drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +81 −3 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ ((jpeg_irq_status) & (hi)->int_status.resetdone) #define CAM_JPEG_HW_IRQ_IS_ERR(jpeg_irq_status, hi) \ ((jpeg_irq_status) & (hi)->int_status.iserror) #define CAM_JPEG_HW_IRQ_IS_STOP_DONE(jpeg_irq_status, hi) \ ((jpeg_irq_status) & (hi)->int_status.stopdone) #define CAM_JPEG_ENC_RESET_TIMEOUT msecs_to_jiffies(500) Loading Loading @@ -181,7 +183,9 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d", irq_num, irq_status, core_info->core_state); if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) { spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_READY) { encoded_size = cam_io_r_mb(mem_base + core_info->jpeg_enc_hw_info->reg_offset. Loading @@ -191,22 +195,42 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) encoded_size, core_info->irq_cb.data); } else { CAM_ERR(CAM_JPEG, "unexpected done"); CAM_ERR(CAM_JPEG, "unexpected done, no cb"); } } else { CAM_ERR(CAM_JPEG, "unexpected done irq"); } core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; spin_unlock(&jpeg_enc_dev->hw_lock); } if (CAM_JPEG_HW_IRQ_IS_RESET_ACK(irq_status, hw_info)) { spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) { core_info->core_state = CAM_JPEG_ENC_CORE_READY; complete(&jpeg_enc_dev->hw_complete); } else { CAM_ERR(CAM_JPEG, "unexpected reset irq"); } spin_unlock(&jpeg_enc_dev->hw_lock); } if (CAM_JPEG_HW_IRQ_IS_STOP_DONE(irq_status, hw_info)) { spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) { core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; complete(&jpeg_enc_dev->hw_complete); if (core_info->irq_cb.jpeg_hw_mgr_cb) { core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, -1, core_info->irq_cb.data); } } else { CAM_ERR(CAM_JPEG, "unexpected abort irq"); } spin_unlock(&jpeg_enc_dev->hw_lock); } /* Unexpected/unintended HW interrupt */ if (CAM_JPEG_HW_IRQ_IS_ERR(irq_status, hw_info)) { spin_lock(&jpeg_enc_dev->hw_lock); core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; CAM_ERR_RATE_LIMIT(CAM_JPEG, "error irq_num %d irq_status = %x , core_state %d", Loading @@ -217,6 +241,7 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) -1, core_info->irq_cb.data); } spin_unlock(&jpeg_enc_dev->hw_lock); } return IRQ_HANDLED; Loading Loading @@ -244,14 +269,18 @@ int cam_jpeg_enc_reset_hw(void *data, hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; mutex_lock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) { CAM_ERR(CAM_JPEG, "alrady resetting"); spin_unlock(&jpeg_enc_dev->hw_lock); mutex_unlock(&core_info->core_mutex); return 0; } reinit_completion(&jpeg_enc_dev->hw_complete); core_info->core_state = CAM_JPEG_ENC_CORE_RESETTING; spin_unlock(&jpeg_enc_dev->hw_lock); cam_io_w_mb(hw_info->reg_val.int_mask_disable_all, mem_base + hw_info->reg_offset.int_mask); Loading @@ -269,6 +298,7 @@ int cam_jpeg_enc_reset_hw(void *data, core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; } mutex_unlock(&core_info->core_mutex); return 0; } Loading Loading @@ -303,6 +333,54 @@ int cam_jpeg_enc_start_hw(void *data, return 0; } int cam_jpeg_enc_stop_hw(void *data, void *stop_args, uint32_t arg_size) { struct cam_hw_info *jpeg_enc_dev = data; struct cam_jpeg_enc_device_core_info *core_info = NULL; struct cam_hw_soc_info *soc_info = NULL; struct cam_jpeg_enc_device_hw_info *hw_info = NULL; void __iomem *mem_base; unsigned long rem_jiffies; if (!jpeg_enc_dev) { CAM_ERR(CAM_JPEG, "Invalid args"); return -EINVAL; } soc_info = &jpeg_enc_dev->soc_info; core_info = (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev-> core_info; hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; mutex_unlock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) { CAM_ERR(CAM_JPEG, "alrady stopping"); spin_unlock(&jpeg_enc_dev->hw_lock); mutex_unlock(&core_info->core_mutex); return 0; } reinit_completion(&jpeg_enc_dev->hw_complete); core_info->core_state = CAM_JPEG_ENC_CORE_ABORTING; spin_unlock(&jpeg_enc_dev->hw_lock); cam_io_w_mb(hw_info->reg_val.hw_cmd_stop, mem_base + hw_info->reg_offset.hw_cmd); rem_jiffies = wait_for_completion_timeout(&jpeg_enc_dev->hw_complete, CAM_JPEG_ENC_RESET_TIMEOUT); if (!rem_jiffies) { CAM_ERR(CAM_JPEG, "error Reset Timeout"); core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; } mutex_unlock(&core_info->core_mutex); return 0; } int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { Loading drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h +5 −0 Original line number Diff line number Diff line Loading @@ -37,12 +37,14 @@ struct cam_jpeg_enc_regval { uint32_t int_mask_enable_all; uint32_t hw_cmd_start; uint32_t reset_cmd; uint32_t hw_cmd_stop; }; struct cam_jpeg_enc_int_status { uint32_t framedone; uint32_t resetdone; uint32_t iserror; uint32_t stopdone; }; struct cam_jpeg_enc_device_hw_info { Loading @@ -55,6 +57,7 @@ enum cam_jpeg_enc_core_state { CAM_JPEG_ENC_CORE_NOT_READY, CAM_JPEG_ENC_CORE_READY, CAM_JPEG_ENC_CORE_RESETTING, CAM_JPEG_ENC_CORE_ABORTING, CAM_JPEG_ENC_CORE_STATE_MAX, }; Loading @@ -73,6 +76,8 @@ int cam_jpeg_enc_deinit_hw(void *device_priv, void *init_hw_args, uint32_t arg_size); int cam_jpeg_enc_start_hw(void *device_priv, void *start_hw_args, uint32_t arg_size); int cam_jpeg_enc_stop_hw(void *device_priv, void *stop_hw_args, uint32_t arg_size); int cam_jpeg_enc_reset_hw(void *device_priv, void *reset_hw_args, uint32_t arg_size); int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type, Loading Loading
drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c +15 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,20 @@ static int __cam_jpeg_ctx_handle_buf_done_in_acquired(void *ctx, return cam_context_buf_done_from_hw(ctx, done, evt_id); } static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx, struct cam_start_stop_dev_cmd *cmd) { int rc; rc = cam_context_stop_dev_to_hw(ctx); if (rc) { CAM_ERR(CAM_JPEG, "Failed in Stop dev, rc=%d", rc); return rc; } return rc; } /* top state machine */ static struct cam_ctx_ops cam_jpeg_ctx_state_machine[CAM_CTX_STATE_MAX] = { Loading @@ -85,6 +99,7 @@ static struct cam_ctx_ops .ioctl_ops = { .release_dev = __cam_jpeg_ctx_release_dev_in_acquired, .config_dev = __cam_jpeg_ctx_config_dev_in_acquired, .stop_dev = __cam_jpeg_ctx_stop_dev_in_acquired, }, .crm_ops = { }, .irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired, Loading
drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +104 −6 Original line number Diff line number Diff line Loading @@ -80,11 +80,23 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) dev_type = ctx_data->jpeg_dev_acquire_info.dev_type; mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex); p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; if (hw_mgr->device_in_use[dev_type][0] == false || p_cfg_req == NULL) { CAM_ERR(CAM_JPEG, "irq for old request %d", rc); mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); return -EINVAL; } irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb; irq_cb.data = NULL; irq_cb.b_set_cb = false; if (!hw_mgr->devices[dev_type][0]->hw_ops.process_cmd) { CAM_ERR(CAM_JPEG, "process_cmd null "); mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); return -EINVAL; } rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd( Loading @@ -93,6 +105,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) &irq_cb, sizeof(irq_cb)); if (rc) { CAM_ERR(CAM_JPEG, "CMD_SET_IRQ_CB failed %d", rc); mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); return rc; } Loading @@ -103,9 +116,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) CAM_ERR(CAM_JPEG, "Failed to Deinit %d HW", dev_type); } mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex); hw_mgr->device_in_use[dev_type][0] = false; p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL; mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex); Loading Loading @@ -167,7 +178,6 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data) list_add_tail(&p_cfg_req->list, &hw_mgr->free_req_list); return rc; } Loading Loading @@ -319,8 +329,11 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) return -EINVAL; } mutex_lock(&hw_mgr->hw_mgr_mutex); if (list_empty(&hw_mgr->hw_config_req_list)) { CAM_DBG(CAM_JPEG, "no available request"); mutex_unlock(&hw_mgr->hw_mgr_mutex); rc = -EFAULT; goto end; } Loading @@ -329,11 +342,11 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) struct cam_jpeg_hw_cfg_req, list); if (!p_cfg_req) { CAM_ERR(CAM_JPEG, "no request"); mutex_unlock(&hw_mgr->hw_mgr_mutex); rc = -EFAULT; goto end; } mutex_lock(&hw_mgr->hw_mgr_mutex); if (false == hw_mgr->device_in_use[p_cfg_req->dev_type][0]) { hw_mgr->device_in_use[p_cfg_req->dev_type][0] = true; hw_mgr->dev_hw_cfg_args[p_cfg_req->dev_type][0] = p_cfg_req; Loading @@ -344,6 +357,7 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) rc = -EFAULT; goto end; } mutex_unlock(&hw_mgr->hw_mgr_mutex); config_args = (struct cam_hw_config_args *)&p_cfg_req->hw_cfg_args; Loading Loading @@ -464,7 +478,7 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data) hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0); if (rc) { CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", CAM_ERR(CAM_JPEG, "Failed to start hw %d", rc); goto end_callcb; } Loading Loading @@ -553,12 +567,12 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) goto err_after_dq_free_list; } mutex_unlock(&hw_mgr->hw_mgr_mutex); task_data = (struct cam_jpeg_process_frame_work_data_t *) task->payload; if (!task_data) { CAM_ERR(CAM_JPEG, "task_data is NULL"); mutex_unlock(&hw_mgr->hw_mgr_mutex); rc = -EINVAL; goto err_after_dq_free_list; } Loading @@ -567,6 +581,7 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args) p_cfg_req->hw_cfg_args.num_hw_update_entries); list_add_tail(&p_cfg_req->list, &hw_mgr->hw_config_req_list); mutex_unlock(&hw_mgr->hw_mgr_mutex); task_data->data = (void *)(int64_t)p_cfg_req->dev_type; task_data->request_id = request_id; Loading Loading @@ -719,6 +734,88 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, return rc; } static int cam_jpeg_mgr_flush(void *hw_mgr_priv, struct cam_jpeg_hw_ctx_data *ctx_data) { int rc = 0; struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv; uint32_t dev_type; struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL; struct cam_jpeg_hw_cfg_req *cfg_req, *req_temp; if (!hw_mgr || !ctx_data) { CAM_ERR(CAM_JPEG, "Invalid args"); return -EINVAL; } dev_type = ctx_data->jpeg_dev_acquire_info.dev_type; p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; if (hw_mgr->device_in_use[dev_type][0] == true && p_cfg_req != NULL) { if ((struct cam_jpeg_hw_ctx_data *)p_cfg_req-> hw_cfg_args.ctxt_to_hw_map == ctx_data) { /* stop reset Unregister CB and deinit */ if (hw_mgr->devices[dev_type][0]->hw_ops.stop) { rc = hw_mgr->devices[dev_type][0]->hw_ops.stop( hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0); if (rc) CAM_ERR(CAM_JPEG, "stop fail %d", rc); } else { CAM_ERR(CAM_JPEG, "op stop null "); rc = -EINVAL; } } hw_mgr->device_in_use[dev_type][0] = false; p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0]; hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL; } list_for_each_entry_safe(cfg_req, req_temp, &hw_mgr->hw_config_req_list, list) { if ((struct cam_jpeg_hw_ctx_data *)cfg_req-> hw_cfg_args.ctxt_to_hw_map != ctx_data) continue; CAM_INFO(CAM_JPEG, "deleting req %pK", cfg_req); list_del_init(&cfg_req->list); } return rc; } static int cam_jpeg_mgr_hw_stop(void *hw_mgr_priv, void *stop_hw_args) { int rc; struct cam_hw_stop_args *stop_args = (struct cam_hw_stop_args *)stop_hw_args; struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv; struct cam_jpeg_hw_ctx_data *ctx_data = NULL; if (!hw_mgr || !stop_args || !stop_args->ctxt_to_hw_map) { CAM_ERR(CAM_JPEG, "Invalid args"); return -EINVAL; } mutex_lock(&hw_mgr->hw_mgr_mutex); ctx_data = (struct cam_jpeg_hw_ctx_data *)stop_args->ctxt_to_hw_map; if (!ctx_data->in_use) { CAM_ERR(CAM_JPEG, "ctx is not in use"); mutex_unlock(&hw_mgr->hw_mgr_mutex); return -EINVAL; } rc = cam_jpeg_mgr_flush(hw_mgr_priv, ctx_data); if ((rc)) CAM_ERR(CAM_JPEG, "flush failed %d", rc); mutex_unlock(&hw_mgr->hw_mgr_mutex); return rc; } static int cam_jpeg_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args) { int rc; Loading Loading @@ -1184,6 +1281,7 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl) hw_mgr_intf->hw_release = cam_jpeg_mgr_release_hw; hw_mgr_intf->hw_prepare_update = cam_jpeg_mgr_prepare_hw_update; hw_mgr_intf->hw_config = cam_jpeg_mgr_config_hw; hw_mgr_intf->hw_stop = cam_jpeg_mgr_hw_stop; mutex_init(&g_jpeg_hw_mgr.hw_mgr_mutex); spin_lock_init(&g_jpeg_hw_mgr.hw_mgr_lock); Loading
drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_hw_info_ver_4_2_0.h +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ #define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000 #define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a #define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK 0x8000000 #define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_SHIFT 0x0000001b #define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800 #define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b Loading Loading @@ -63,11 +66,13 @@ static struct cam_jpeg_enc_device_hw_info cam_jpeg_enc_hw_info = { .int_mask_enable_all = 0xFFFFFFFF, .hw_cmd_start = 0x00000001, .reset_cmd = 0x00032093, .hw_cmd_stop = 0x00000002, }, .int_status = { .framedone = CAM_JPEG_HW_MASK_COMP_FRAMEDONE, .resetdone = CAM_JPEG_HW_MASK_COMP_RESET_ACK, .iserror = CAM_JPEG_HW_MASK_COMP_ERR, .stopdone = CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK, } }; Loading
drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +81 −3 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ ((jpeg_irq_status) & (hi)->int_status.resetdone) #define CAM_JPEG_HW_IRQ_IS_ERR(jpeg_irq_status, hi) \ ((jpeg_irq_status) & (hi)->int_status.iserror) #define CAM_JPEG_HW_IRQ_IS_STOP_DONE(jpeg_irq_status, hi) \ ((jpeg_irq_status) & (hi)->int_status.stopdone) #define CAM_JPEG_ENC_RESET_TIMEOUT msecs_to_jiffies(500) Loading Loading @@ -181,7 +183,9 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d", irq_num, irq_status, core_info->core_state); if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) { spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_READY) { encoded_size = cam_io_r_mb(mem_base + core_info->jpeg_enc_hw_info->reg_offset. Loading @@ -191,22 +195,42 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) encoded_size, core_info->irq_cb.data); } else { CAM_ERR(CAM_JPEG, "unexpected done"); CAM_ERR(CAM_JPEG, "unexpected done, no cb"); } } else { CAM_ERR(CAM_JPEG, "unexpected done irq"); } core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; spin_unlock(&jpeg_enc_dev->hw_lock); } if (CAM_JPEG_HW_IRQ_IS_RESET_ACK(irq_status, hw_info)) { spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) { core_info->core_state = CAM_JPEG_ENC_CORE_READY; complete(&jpeg_enc_dev->hw_complete); } else { CAM_ERR(CAM_JPEG, "unexpected reset irq"); } spin_unlock(&jpeg_enc_dev->hw_lock); } if (CAM_JPEG_HW_IRQ_IS_STOP_DONE(irq_status, hw_info)) { spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) { core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; complete(&jpeg_enc_dev->hw_complete); if (core_info->irq_cb.jpeg_hw_mgr_cb) { core_info->irq_cb.jpeg_hw_mgr_cb(irq_status, -1, core_info->irq_cb.data); } } else { CAM_ERR(CAM_JPEG, "unexpected abort irq"); } spin_unlock(&jpeg_enc_dev->hw_lock); } /* Unexpected/unintended HW interrupt */ if (CAM_JPEG_HW_IRQ_IS_ERR(irq_status, hw_info)) { spin_lock(&jpeg_enc_dev->hw_lock); core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; CAM_ERR_RATE_LIMIT(CAM_JPEG, "error irq_num %d irq_status = %x , core_state %d", Loading @@ -217,6 +241,7 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) -1, core_info->irq_cb.data); } spin_unlock(&jpeg_enc_dev->hw_lock); } return IRQ_HANDLED; Loading Loading @@ -244,14 +269,18 @@ int cam_jpeg_enc_reset_hw(void *data, hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; mutex_lock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) { CAM_ERR(CAM_JPEG, "alrady resetting"); spin_unlock(&jpeg_enc_dev->hw_lock); mutex_unlock(&core_info->core_mutex); return 0; } reinit_completion(&jpeg_enc_dev->hw_complete); core_info->core_state = CAM_JPEG_ENC_CORE_RESETTING; spin_unlock(&jpeg_enc_dev->hw_lock); cam_io_w_mb(hw_info->reg_val.int_mask_disable_all, mem_base + hw_info->reg_offset.int_mask); Loading @@ -269,6 +298,7 @@ int cam_jpeg_enc_reset_hw(void *data, core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; } mutex_unlock(&core_info->core_mutex); return 0; } Loading Loading @@ -303,6 +333,54 @@ int cam_jpeg_enc_start_hw(void *data, return 0; } int cam_jpeg_enc_stop_hw(void *data, void *stop_args, uint32_t arg_size) { struct cam_hw_info *jpeg_enc_dev = data; struct cam_jpeg_enc_device_core_info *core_info = NULL; struct cam_hw_soc_info *soc_info = NULL; struct cam_jpeg_enc_device_hw_info *hw_info = NULL; void __iomem *mem_base; unsigned long rem_jiffies; if (!jpeg_enc_dev) { CAM_ERR(CAM_JPEG, "Invalid args"); return -EINVAL; } soc_info = &jpeg_enc_dev->soc_info; core_info = (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev-> core_info; hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; mutex_unlock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) { CAM_ERR(CAM_JPEG, "alrady stopping"); spin_unlock(&jpeg_enc_dev->hw_lock); mutex_unlock(&core_info->core_mutex); return 0; } reinit_completion(&jpeg_enc_dev->hw_complete); core_info->core_state = CAM_JPEG_ENC_CORE_ABORTING; spin_unlock(&jpeg_enc_dev->hw_lock); cam_io_w_mb(hw_info->reg_val.hw_cmd_stop, mem_base + hw_info->reg_offset.hw_cmd); rem_jiffies = wait_for_completion_timeout(&jpeg_enc_dev->hw_complete, CAM_JPEG_ENC_RESET_TIMEOUT); if (!rem_jiffies) { CAM_ERR(CAM_JPEG, "error Reset Timeout"); core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY; } mutex_unlock(&core_info->core_mutex); return 0; } int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { Loading
drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h +5 −0 Original line number Diff line number Diff line Loading @@ -37,12 +37,14 @@ struct cam_jpeg_enc_regval { uint32_t int_mask_enable_all; uint32_t hw_cmd_start; uint32_t reset_cmd; uint32_t hw_cmd_stop; }; struct cam_jpeg_enc_int_status { uint32_t framedone; uint32_t resetdone; uint32_t iserror; uint32_t stopdone; }; struct cam_jpeg_enc_device_hw_info { Loading @@ -55,6 +57,7 @@ enum cam_jpeg_enc_core_state { CAM_JPEG_ENC_CORE_NOT_READY, CAM_JPEG_ENC_CORE_READY, CAM_JPEG_ENC_CORE_RESETTING, CAM_JPEG_ENC_CORE_ABORTING, CAM_JPEG_ENC_CORE_STATE_MAX, }; Loading @@ -73,6 +76,8 @@ int cam_jpeg_enc_deinit_hw(void *device_priv, void *init_hw_args, uint32_t arg_size); int cam_jpeg_enc_start_hw(void *device_priv, void *start_hw_args, uint32_t arg_size); int cam_jpeg_enc_stop_hw(void *device_priv, void *stop_hw_args, uint32_t arg_size); int cam_jpeg_enc_reset_hw(void *device_priv, void *reset_hw_args, uint32_t arg_size); int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type, Loading