Loading drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.c +27 −27 Original line number Original line Diff line number Diff line Loading @@ -139,26 +139,23 @@ static int ais_ife_cmd_reserve(struct ais_ife_dev *p_ife_dev, rc = csid_drv->hw_ops.init( rc = csid_drv->hw_ops.init( csid_drv->hw_priv, rdi_init, cmd_size); csid_drv->hw_priv, rdi_init, cmd_size); if (!rc) { if (rc) goto fail_csid_init; rc = vfe_drv->hw_ops.init( rc = vfe_drv->hw_ops.init( vfe_drv->hw_priv, rdi_init, cmd_size); vfe_drv->hw_priv, rdi_init, cmd_size); if (rc) if (rc) goto fail_vfe_init; goto fail_vfe_init; } if (!rc) { rc = csid_drv->hw_ops.reserve( rc = csid_drv->hw_ops.reserve( csid_drv->hw_priv, rdi_init, cmd_size); csid_drv->hw_priv, rdi_init, cmd_size); if (rc) if (rc) goto fail_csid_reserve; goto fail_csid_reserve; } if (!rc) { rc = vfe_drv->hw_ops.reserve( rc = vfe_drv->hw_ops.reserve( vfe_drv->hw_priv, rdi_init, cmd_size); vfe_drv->hw_priv, rdi_init, cmd_size); if (rc) if (rc) goto fail_vfe_reserve; goto fail_vfe_reserve; } return rc; return rc; Loading @@ -171,7 +168,7 @@ static int ais_ife_cmd_reserve(struct ais_ife_dev *p_ife_dev, fail_vfe_init: fail_vfe_init: csid_drv->hw_ops.deinit( csid_drv->hw_ops.deinit( csid_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit)); csid_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit)); fail_csid_init: return rc; return rc; } } Loading @@ -189,6 +186,7 @@ static int ais_ife_cmd_release(struct ais_ife_dev *p_ife_dev, rc = csid_drv->hw_ops.release( rc = csid_drv->hw_ops.release( csid_drv->hw_priv, rdi_deinit, cmd_size); csid_drv->hw_priv, rdi_deinit, cmd_size); tmp = vfe_drv->hw_ops.release( tmp = vfe_drv->hw_ops.release( vfe_drv->hw_priv, rdi_deinit, cmd_size); vfe_drv->hw_priv, rdi_deinit, cmd_size); if (!rc) if (!rc) Loading Loading @@ -313,20 +311,22 @@ static int ais_ife_driver_cmd(struct ais_ife_dev *p_ife_dev, void *arg) cmd->size)) { cmd->size)) { rc = -EFAULT; rc = -EFAULT; } else { } else { rc = csid_drv->hw_ops.start( rc = vfe_drv->hw_ops.start(vfe_drv->hw_priv, csid_drv->hw_priv, &rdi_start, cmd->size); &rdi_start, cmd->size); if (!rc) { if (!rc) { rc = csid_drv->hw_ops.start( csid_drv->hw_priv, &rdi_start, cmd->size); if (rc) { struct ais_ife_rdi_stop_args rdi_stop; struct ais_ife_rdi_stop_args rdi_stop; rdi_stop.path = rdi_start.path; rdi_stop.path = rdi_start.path; rc = vfe_drv->hw_ops.start(vfe_drv->hw_priv, vfe_drv->hw_ops.stop(vfe_drv->hw_priv, &rdi_start, cmd->size); if (rc) csid_drv->hw_ops.stop(csid_drv->hw_priv, &rdi_stop, sizeof(rdi_stop)); &rdi_stop, sizeof(rdi_stop)); } } } } } } } break; break; case AIS_IFE_STOP: { case AIS_IFE_STOP: { struct ais_ife_rdi_stop_args rdi_stop; struct ais_ife_rdi_stop_args rdi_stop; Loading @@ -341,10 +341,10 @@ static int ais_ife_driver_cmd(struct ais_ife_dev *p_ife_dev, void *arg) } else { } else { int tmp; int tmp; rc = vfe_drv->hw_ops.stop( rc = csid_drv->hw_ops.stop( vfe_drv->hw_priv, &rdi_stop, cmd->size); tmp = csid_drv->hw_ops.stop( csid_drv->hw_priv, &rdi_stop, cmd->size); csid_drv->hw_priv, &rdi_stop, cmd->size); tmp = vfe_drv->hw_ops.stop( vfe_drv->hw_priv, &rdi_stop, cmd->size); if (!rc) if (!rc) rc = tmp; rc = tmp; } } Loading drivers/media/platform/msm/ais/ais_isp/csid_hw/ais_ife_csid_core.c +25 −21 Original line number Original line Diff line number Diff line Loading @@ -214,10 +214,8 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw, return -EINVAL; return -EINVAL; } } reset_strb_addr = reset_strb_addr = csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr; csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr; complete = &csid_hw->csid_rdi_complete[id]; complete = &csid_hw->csid_rdi_complete[id]; /* Enable path reset done interrupt */ /* Enable path reset done interrupt */ val = cam_io_r_mb(soc_info->reg_map[0].mem_base + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + Loading @@ -226,7 +224,7 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw, cam_io_w_mb(val, soc_info->reg_map[0].mem_base + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); init_completion(complete); reinit_completion(complete); reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all; reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all; /* Reset the corresponding ife csid path */ /* Reset the corresponding ife csid path */ Loading @@ -235,11 +233,11 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw, rc = wait_for_completion_timeout(complete, rc = wait_for_completion_timeout(complete, msecs_to_jiffies(IFE_CSID_TIMEOUT)); msecs_to_jiffies(IFE_CSID_TIMEOUT)); if (rc <= 0) { if (rc) { CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d", rc = 0; csid_hw->hw_intf->hw_idx, } else { reset_path, rc); CAM_ERR(CAM_ISP, "CSID:%d RDI%d reset fail", if (rc == 0) csid_hw->hw_intf->hw_idx, reset_path, rc); rc = -ETIMEDOUT; rc = -ETIMEDOUT; } } Loading Loading @@ -815,6 +813,7 @@ static int ais_ife_csid_enable_rdi_path( soc_info = &csid_hw->hw_info->soc_info; soc_info = &csid_hw->hw_info->soc_info; path_data = &csid_hw->rdi_cfg[id]; path_data = &csid_hw->rdi_cfg[id]; path_data->init_frame_drop = 1; path_data->sof_cnt = 0; path_data->sof_cnt = 0; /* Enable the required RDI interrupts */ /* Enable the required RDI interrupts */ Loading Loading @@ -1326,7 +1325,7 @@ static int ais_ife_csid_start(void *hw_priv, void *start_args, if (start_cmd->path >= csid_reg->cmn_reg->num_rdis || if (start_cmd->path >= csid_reg->cmn_reg->num_rdis || !csid_reg->rdi_reg[start_cmd->path]) { !csid_reg->rdi_reg[start_cmd->path]) { CAM_DBG(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", csid_hw->hw_intf->hw_idx, start_cmd->path); csid_hw->hw_intf->hw_idx, start_cmd->path); rc = -EINVAL; rc = -EINVAL; goto end; goto end; Loading Loading @@ -1367,7 +1366,7 @@ static int ais_ife_csid_stop(void *hw_priv, if (stop_cmd->path >= csid_reg->cmn_reg->num_rdis || if (stop_cmd->path >= csid_reg->cmn_reg->num_rdis || !csid_reg->rdi_reg[stop_cmd->path]) { !csid_reg->rdi_reg[stop_cmd->path]) { CAM_DBG(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", csid_hw->hw_intf->hw_idx, stop_cmd->path); csid_hw->hw_intf->hw_idx, stop_cmd->path); rc = -EINVAL; rc = -EINVAL; goto end; goto end; Loading Loading @@ -1677,6 +1676,7 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data) const struct ais_ife_csid_rdi_reg_offset *rdi_reg; const struct ais_ife_csid_rdi_reg_offset *rdi_reg; uint32_t i; uint32_t i; uint32_t val, val2; uint32_t val, val2; uint32_t warn_cnt = 0; bool fatal_err_detected = false; bool fatal_err_detected = false; uint32_t sof_irq_debug_en = 0; uint32_t sof_irq_debug_en = 0; unsigned long flags; unsigned long flags; Loading Loading @@ -1778,27 +1778,29 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data) } } if (irq_status[CSID_IRQ_STATUS_RX] & if (irq_status[CSID_IRQ_STATUS_RX] & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) { CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) { csid_hw->error_irq_count++; warn_cnt++; } } if (irq_status[CSID_IRQ_STATUS_RX] & if (irq_status[CSID_IRQ_STATUS_RX] & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) { CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) { csid_hw->error_irq_count++; warn_cnt++; } } if (irq_status[CSID_IRQ_STATUS_RX] & if (irq_status[CSID_IRQ_STATUS_RX] & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) { CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) { csid_hw->error_irq_count++; warn_cnt++; } } if (irq_status[CSID_IRQ_STATUS_RX] & if (irq_status[CSID_IRQ_STATUS_RX] & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) { CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) { csid_hw->error_irq_count++; warn_cnt++; } } } } csid_hw->error_irq_count += warn_cnt; if (csid_hw->error_irq_count > if (csid_hw->error_irq_count > AIS_IFE_CSID_MAX_IRQ_ERROR_COUNT) { AIS_IFE_CSID_MAX_IRQ_ERROR_COUNT) { fatal_err_detected = true; fatal_err_detected = true; csid_hw->error_irq_count = 0; csid_hw->error_irq_count = 0; } else if (csid_hw->error_irq_count) { } else if (warn_cnt) { uint64_t timestamp; uint64_t timestamp; timestamp = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); timestamp = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); Loading Loading @@ -1951,18 +1953,20 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data) (path_data->init_frame_drop) && (path_data->init_frame_drop) && (path_data->state == (path_data->state == AIS_ISP_RESOURCE_STATE_STREAMING)) { AIS_ISP_RESOURCE_STATE_STREAMING)) { path_data[i].sof_cnt++; path_data->sof_cnt++; CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP, "CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d", "CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d", csid_hw->hw_intf->hw_idx, i, csid_hw->hw_intf->hw_idx, i, path_data[i].sof_cnt, path_data->sof_cnt, path_data->init_frame_drop); path_data->init_frame_drop); if (path_data[i].sof_cnt == if (path_data->sof_cnt == path_data->init_frame_drop) { path_data->init_frame_drop) { cam_io_w_mb(AIS_CSID_RESUME_AT_FRAME_BOUNDARY, cam_io_w_mb(AIS_CSID_RESUME_AT_FRAME_BOUNDARY, soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base + rdi_reg->csid_rdi_ctrl_addr); rdi_reg->csid_rdi_ctrl_addr); path_data->init_frame_drop = 0; if (!(csid_hw->csid_debug & if (!(csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)) { CSID_DEBUG_ENABLE_SOF_IRQ)) { val = cam_io_r_mb( val = cam_io_r_mb( Loading drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c +67 −31 Original line number Original line Diff line number Diff line Loading @@ -99,7 +99,7 @@ static int ais_vfe_bus_hw_init(struct ais_vfe_hw_core_info *core_info) cam_io_w_mb(core_info->irq_mask0, cam_io_w_mb(core_info->irq_mask0, core_info->mem_base + AIS_VFE_IRQ_MASK0); core_info->mem_base + AIS_VFE_IRQ_MASK0); cam_io_w_mb(0x7800, cam_io_w_mb(0x7801, core_info->mem_base + bus_hw_irq_regs[0].mask_reg_offset); core_info->mem_base + bus_hw_irq_regs[0].mask_reg_offset); cam_io_w_mb(0x0, cam_io_w_mb(0x0, core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset); core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset); Loading Loading @@ -220,7 +220,8 @@ static int ais_vfe_reset(void *hw_priv, CAM_DBG(CAM_ISP, "waiting for vfe reset complete"); CAM_DBG(CAM_ISP, "waiting for vfe reset complete"); /* Wait for Completion or Timeout of 500ms */ /* Wait for Completion or Timeout of 500ms */ rc = wait_for_completion_timeout(&vfe_hw->hw_complete, 500); rc = wait_for_completion_timeout(&vfe_hw->hw_complete, msecs_to_jiffies(500)); if (rc) { if (rc) { rc = 0; rc = 0; } else { } else { Loading Loading @@ -622,17 +623,28 @@ int ais_vfe_stop(void *hw_priv, void *stop_args, uint32_t arg_size) rdi_path->state = AIS_ISP_RESOURCE_STATE_INIT_HW; rdi_path->state = AIS_ISP_RESOURCE_STATE_INIT_HW; core_info->bus_wr_mask1 &= ~(1 << stop_cmd->path); cam_io_w_mb(core_info->bus_wr_mask1, core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset); /* Disable WM and reg-update */ /* Disable WM and reg-update */ cam_io_w_mb(0x0, core_info->mem_base + client_regs->cfg); cam_io_w_mb(0x0, core_info->mem_base + client_regs->cfg); cam_io_w_mb(AIS_VFE_REGUP_RDI_ALL, core_info->mem_base + cam_io_w_mb(AIS_VFE_REGUP_RDI_ALL, core_info->mem_base + top_hw_info->common_reg->reg_update_cmd); top_hw_info->common_reg->reg_update_cmd); /* issue bus wr reset and wait for reset ack */ reinit_completion(&vfe_hw->hw_complete); cam_io_w_mb((1 << stop_cmd->path), core_info->mem_base + cam_io_w_mb((1 << stop_cmd->path), core_info->mem_base + bus_hw_info->common_reg.sw_reset); bus_hw_info->common_reg.sw_reset); core_info->bus_wr_mask1 &= ~(1 << stop_cmd->path); /* Wait for completion or timeout of 50ms */ cam_io_w_mb(core_info->bus_wr_mask1, rc = wait_for_completion_timeout(&vfe_hw->hw_complete, core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset); msecs_to_jiffies(50)); if (rc) rc = 0; else CAM_WARN(CAM_ISP, "Reset Bus WR timeout"); ais_clear_rdi_path(rdi_path); ais_clear_rdi_path(rdi_path); Loading Loading @@ -896,7 +908,8 @@ static int ais_vfe_handle_error( static void ais_vfe_bus_handle_client_frame_done( static void ais_vfe_bus_handle_client_frame_done( struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_core_info *core_info, enum ais_ife_output_path_id path) enum ais_ife_output_path_id path, uint32_t last_addr) { { struct ais_vfe_rdi_output *rdi_path = NULL; struct ais_vfe_rdi_output *rdi_path = NULL; struct ais_vfe_buffer_t *vfe_buf = NULL; struct ais_vfe_buffer_t *vfe_buf = NULL; Loading Loading @@ -925,7 +938,7 @@ static void ais_vfe_bus_handle_client_frame_done( CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d DQ %d (0x%x) FIFO:%d|0x%x", CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d DQ %d (0x%x) FIFO:%d|0x%x", core_info->vfe_idx, path, core_info->vfe_idx, path, vfe_buf->bufIdx, vfe_buf->iova_addr, vfe_buf->bufIdx, vfe_buf->iova_addr, rdi_path->num_buffer_hw_q, rdi_path->last_addr); rdi_path->num_buffer_hw_q, last_addr); core_info->event.type = AIS_IFE_MSG_FRAME_DONE; core_info->event.type = AIS_IFE_MSG_FRAME_DONE; core_info->event.path = path; core_info->event.path = path; Loading @@ -937,15 +950,18 @@ static void ais_vfe_bus_handle_client_frame_done( core_info->event_cb(core_info->event_cb_priv, core_info->event_cb(core_info->event_cb_priv, &core_info->event); &core_info->event); if (rdi_path->last_addr == vfe_buf->iova_addr) if (last_addr == vfe_buf->iova_addr) last_addr_match = true; last_addr_match = true; else CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr", core_info->vfe_idx, vfe_buf->bufIdx); list_add_tail(&vfe_buf->list, &rdi_path->free_buffer_list); list_add_tail(&vfe_buf->list, &rdi_path->free_buffer_list); } } if (!last_addr_match) if (!last_addr_match) CAM_ERR(CAM_ISP, "IFE%d BUF| RDI%d NO MATCH addr 0x%x", CAM_ERR(CAM_ISP, "IFE%d BUF| RDI%d NO MATCH addr 0x%x", core_info->vfe_idx, path, rdi_path->last_addr); core_info->vfe_idx, path, last_addr); ais_vfe_queue_to_hw(core_info, path); ais_vfe_queue_to_hw(core_info, path); Loading @@ -954,9 +970,10 @@ static void ais_vfe_bus_handle_client_frame_done( static int ais_vfe_bus_handle_frame_done( static int ais_vfe_bus_handle_frame_done( struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_core_info *core_info, uint32_t client_mask) struct ais_vfe_hw_work_data *work_data) { { struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[0]; struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[0]; uint32_t client_mask = work_data->bus_wr_status[1]; uint32_t client; uint32_t client; int rc = 0; int rc = 0; Loading @@ -971,19 +988,18 @@ static int ais_vfe_bus_handle_frame_done( if (client_mask & (0x1 << client)) { if (client_mask & (0x1 << client)) { //process frame done //process frame done ais_vfe_bus_handle_client_frame_done(core_info, client); ais_vfe_bus_handle_client_frame_done(core_info, client, work_data->last_addr[client]); } } } } return rc; return rc; } } static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw, static void ais_vfe_irq_fill_bus_wr_status( struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_work_data *work_data) struct ais_vfe_hw_work_data *work_data) { { int rc = 0; uint32_t vfe_bus_status[3] = {}; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_irq_register_set *bus_hw_irq_regs = NULL; struct ais_irq_register_set *bus_hw_irq_regs = NULL; struct ais_vfe_bus_ver2_reg_offset_bus_client *client_regs = NULL; struct ais_vfe_bus_ver2_reg_offset_bus_client *client_regs = NULL; Loading @@ -993,53 +1009,72 @@ static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw, bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set; bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set; client_regs = &bus_hw_info->bus_client_reg[client]; client_regs = &bus_hw_info->bus_client_reg[client]; vfe_bus_status[0] = cam_io_r_mb(core_info->mem_base + work_data->bus_wr_status[0] = cam_io_r_mb(core_info->mem_base + bus_hw_irq_regs[0].status_reg_offset); bus_hw_irq_regs[0].status_reg_offset); vfe_bus_status[1] = cam_io_r_mb(core_info->mem_base + work_data->bus_wr_status[1] = cam_io_r_mb(core_info->mem_base + bus_hw_irq_regs[1].status_reg_offset); bus_hw_irq_regs[1].status_reg_offset); vfe_bus_status[2] = cam_io_r_mb(core_info->mem_base + work_data->bus_wr_status[2] = cam_io_r_mb(core_info->mem_base + bus_hw_irq_regs[2].status_reg_offset); bus_hw_irq_regs[2].status_reg_offset); if (vfe_bus_status[1]) { if (work_data->bus_wr_status[1]) { struct ais_vfe_rdi_output *p_rdi; struct ais_vfe_rdi_output *p_rdi; for (client = 0 ; client < AIS_IFE_PATH_MAX; client++) { for (client = 0 ; client < AIS_IFE_PATH_MAX; client++) { if (vfe_bus_status[1] & (0x1 << client)) { if (work_data->bus_wr_status[1] & (0x1 << client)) { p_rdi = &core_info->rdi_out[client]; p_rdi = &core_info->rdi_out[client]; client_regs = client_regs = &bus_hw_info->bus_client_reg[client]; &bus_hw_info->bus_client_reg[client]; p_rdi->last_addr = cam_io_r( work_data->last_addr[client] = cam_io_r( core_info->mem_base + core_info->mem_base + client_regs->status0); client_regs->status0); } } } } } } cam_io_w(vfe_bus_status[0], core_info->mem_base + cam_io_w(work_data->bus_wr_status[0], core_info->mem_base + bus_hw_irq_regs[0].clear_reg_offset); bus_hw_irq_regs[0].clear_reg_offset); cam_io_w(vfe_bus_status[1], core_info->mem_base + cam_io_w(work_data->bus_wr_status[1], core_info->mem_base + bus_hw_irq_regs[1].clear_reg_offset); bus_hw_irq_regs[1].clear_reg_offset); cam_io_w(vfe_bus_status[2], core_info->mem_base + cam_io_w(work_data->bus_wr_status[2], core_info->mem_base + bus_hw_irq_regs[2].clear_reg_offset); bus_hw_irq_regs[2].clear_reg_offset); cam_io_w_mb(0x1, core_info->mem_base + cam_io_w_mb(0x1, core_info->mem_base + bus_hw_info->common_reg.irq_reg_info.global_clear_offset); bus_hw_info->common_reg.irq_reg_info.global_clear_offset); } static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw, struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_work_data *work_data) { int rc = 0; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_irq_register_set *bus_hw_irq_regs = NULL; struct ais_vfe_bus_ver2_reg_offset_bus_client *client_regs = NULL; uint32_t client = 0; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set; client_regs = &bus_hw_info->bus_client_reg[client]; CAM_DBG(CAM_ISP, "VFE%d BUS status 0x%x 0x%x 0x%x", core_info->vfe_idx, CAM_DBG(CAM_ISP, "VFE%d BUS status 0x%x 0x%x 0x%x", core_info->vfe_idx, vfe_bus_status[0], vfe_bus_status[1], vfe_bus_status[2]); work_data->bus_wr_status[0], work_data->bus_wr_status[1], work_data->bus_wr_status[2]); if (vfe_bus_status[1]) if (work_data->bus_wr_status[1]) ais_vfe_bus_handle_frame_done(core_info, vfe_bus_status[1]); ais_vfe_bus_handle_frame_done(core_info, work_data); if (vfe_bus_status[0] & 0x7800) { if (work_data->bus_wr_status[0] & 0x7800) { CAM_ERR(CAM_ISP, "VFE%d: WR BUS error occurred status = 0x%x", CAM_ERR(CAM_ISP, "VFE%d: WR BUS error occurred status = 0x%x", core_info->vfe_idx, vfe_bus_status[0]); core_info->vfe_idx, work_data->bus_wr_status[0]); work_data->path = (vfe_bus_status[0] >> 11) & 0xF; work_data->path = (work_data->bus_wr_status[0] >> 11) & 0xF; rc = ais_vfe_handle_error(core_info, work_data); rc = ais_vfe_handle_error(core_info, work_data); } } if (vfe_bus_status[0] & 0x1) { if (work_data->bus_wr_status[0] & 0x1) { CAM_INFO(CAM_ISP, "VFE%d: WR BUS reset completed", CAM_INFO(CAM_ISP, "VFE%d: WR BUS reset completed", core_info->vfe_idx); core_info->vfe_idx); complete(&vfe_hw->hw_complete); } } return rc; return rc; Loading Loading @@ -1194,6 +1229,7 @@ irqreturn_t ais_vfe_irq(int irq_num, void *data) //BUS_WR IRQ //BUS_WR IRQ CAM_DBG(CAM_ISP, "IFE%d BUS_WR", core_info->vfe_idx); CAM_DBG(CAM_ISP, "IFE%d BUS_WR", core_info->vfe_idx); work_data.evt_type = AIS_VFE_HW_IRQ_EVENT_BUS_WR; work_data.evt_type = AIS_VFE_HW_IRQ_EVENT_BUS_WR; ais_vfe_irq_fill_bus_wr_status(core_info, &work_data); ais_vfe_dispatch_irq(vfe_hw, &work_data); ais_vfe_dispatch_irq(vfe_hw, &work_data); } } if (ife_status[1]) { if (ife_status[1]) { Loading drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,8 @@ struct ais_vfe_hw_work_data { enum ais_vfe_hw_irq_event evt_type; enum ais_vfe_hw_irq_event evt_type; uint32_t path; uint32_t path; uint64_t ts; uint64_t ts; uint32_t bus_wr_status[3]; uint32_t last_addr[AIS_IFE_PATH_MAX]; struct ais_ife_rdi_timestamps ts_hw[AIS_IFE_PATH_MAX]; struct ais_ife_rdi_timestamps ts_hw[AIS_IFE_PATH_MAX]; }; }; Loading Loading @@ -93,7 +95,6 @@ struct ais_vfe_rdi_output { struct list_head buffer_hw_q; struct list_head buffer_hw_q; struct list_head free_buffer_list; struct list_head free_buffer_list; uint32_t last_addr; uint64_t frame_cnt; uint64_t frame_cnt; uint64_t sof_ts; uint64_t sof_ts; uint64_t sof_hw_ts; uint64_t sof_hw_ts; Loading drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +2 −1 Original line number Original line Diff line number Diff line Loading @@ -417,7 +417,8 @@ int cam_vfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size) reset_core_args, arg_size); reset_core_args, arg_size); CAM_DBG(CAM_ISP, "waiting for vfe reset complete"); CAM_DBG(CAM_ISP, "waiting for vfe reset complete"); /* Wait for Completion or Timeout of 500ms */ /* Wait for Completion or Timeout of 500ms */ rc = wait_for_completion_timeout(&vfe_hw->hw_complete, 500); rc = wait_for_completion_timeout(&vfe_hw->hw_complete, msecs_to_jiffies(500)); if (!rc) if (!rc) CAM_ERR(CAM_ISP, "Error! Reset Timeout"); CAM_ERR(CAM_ISP, "Error! Reset Timeout"); Loading Loading
drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.c +27 −27 Original line number Original line Diff line number Diff line Loading @@ -139,26 +139,23 @@ static int ais_ife_cmd_reserve(struct ais_ife_dev *p_ife_dev, rc = csid_drv->hw_ops.init( rc = csid_drv->hw_ops.init( csid_drv->hw_priv, rdi_init, cmd_size); csid_drv->hw_priv, rdi_init, cmd_size); if (!rc) { if (rc) goto fail_csid_init; rc = vfe_drv->hw_ops.init( rc = vfe_drv->hw_ops.init( vfe_drv->hw_priv, rdi_init, cmd_size); vfe_drv->hw_priv, rdi_init, cmd_size); if (rc) if (rc) goto fail_vfe_init; goto fail_vfe_init; } if (!rc) { rc = csid_drv->hw_ops.reserve( rc = csid_drv->hw_ops.reserve( csid_drv->hw_priv, rdi_init, cmd_size); csid_drv->hw_priv, rdi_init, cmd_size); if (rc) if (rc) goto fail_csid_reserve; goto fail_csid_reserve; } if (!rc) { rc = vfe_drv->hw_ops.reserve( rc = vfe_drv->hw_ops.reserve( vfe_drv->hw_priv, rdi_init, cmd_size); vfe_drv->hw_priv, rdi_init, cmd_size); if (rc) if (rc) goto fail_vfe_reserve; goto fail_vfe_reserve; } return rc; return rc; Loading @@ -171,7 +168,7 @@ static int ais_ife_cmd_reserve(struct ais_ife_dev *p_ife_dev, fail_vfe_init: fail_vfe_init: csid_drv->hw_ops.deinit( csid_drv->hw_ops.deinit( csid_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit)); csid_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit)); fail_csid_init: return rc; return rc; } } Loading @@ -189,6 +186,7 @@ static int ais_ife_cmd_release(struct ais_ife_dev *p_ife_dev, rc = csid_drv->hw_ops.release( rc = csid_drv->hw_ops.release( csid_drv->hw_priv, rdi_deinit, cmd_size); csid_drv->hw_priv, rdi_deinit, cmd_size); tmp = vfe_drv->hw_ops.release( tmp = vfe_drv->hw_ops.release( vfe_drv->hw_priv, rdi_deinit, cmd_size); vfe_drv->hw_priv, rdi_deinit, cmd_size); if (!rc) if (!rc) Loading Loading @@ -313,20 +311,22 @@ static int ais_ife_driver_cmd(struct ais_ife_dev *p_ife_dev, void *arg) cmd->size)) { cmd->size)) { rc = -EFAULT; rc = -EFAULT; } else { } else { rc = csid_drv->hw_ops.start( rc = vfe_drv->hw_ops.start(vfe_drv->hw_priv, csid_drv->hw_priv, &rdi_start, cmd->size); &rdi_start, cmd->size); if (!rc) { if (!rc) { rc = csid_drv->hw_ops.start( csid_drv->hw_priv, &rdi_start, cmd->size); if (rc) { struct ais_ife_rdi_stop_args rdi_stop; struct ais_ife_rdi_stop_args rdi_stop; rdi_stop.path = rdi_start.path; rdi_stop.path = rdi_start.path; rc = vfe_drv->hw_ops.start(vfe_drv->hw_priv, vfe_drv->hw_ops.stop(vfe_drv->hw_priv, &rdi_start, cmd->size); if (rc) csid_drv->hw_ops.stop(csid_drv->hw_priv, &rdi_stop, sizeof(rdi_stop)); &rdi_stop, sizeof(rdi_stop)); } } } } } } } break; break; case AIS_IFE_STOP: { case AIS_IFE_STOP: { struct ais_ife_rdi_stop_args rdi_stop; struct ais_ife_rdi_stop_args rdi_stop; Loading @@ -341,10 +341,10 @@ static int ais_ife_driver_cmd(struct ais_ife_dev *p_ife_dev, void *arg) } else { } else { int tmp; int tmp; rc = vfe_drv->hw_ops.stop( rc = csid_drv->hw_ops.stop( vfe_drv->hw_priv, &rdi_stop, cmd->size); tmp = csid_drv->hw_ops.stop( csid_drv->hw_priv, &rdi_stop, cmd->size); csid_drv->hw_priv, &rdi_stop, cmd->size); tmp = vfe_drv->hw_ops.stop( vfe_drv->hw_priv, &rdi_stop, cmd->size); if (!rc) if (!rc) rc = tmp; rc = tmp; } } Loading
drivers/media/platform/msm/ais/ais_isp/csid_hw/ais_ife_csid_core.c +25 −21 Original line number Original line Diff line number Diff line Loading @@ -214,10 +214,8 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw, return -EINVAL; return -EINVAL; } } reset_strb_addr = reset_strb_addr = csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr; csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr; complete = &csid_hw->csid_rdi_complete[id]; complete = &csid_hw->csid_rdi_complete[id]; /* Enable path reset done interrupt */ /* Enable path reset done interrupt */ val = cam_io_r_mb(soc_info->reg_map[0].mem_base + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + Loading @@ -226,7 +224,7 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw, cam_io_w_mb(val, soc_info->reg_map[0].mem_base + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); init_completion(complete); reinit_completion(complete); reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all; reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all; /* Reset the corresponding ife csid path */ /* Reset the corresponding ife csid path */ Loading @@ -235,11 +233,11 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw, rc = wait_for_completion_timeout(complete, rc = wait_for_completion_timeout(complete, msecs_to_jiffies(IFE_CSID_TIMEOUT)); msecs_to_jiffies(IFE_CSID_TIMEOUT)); if (rc <= 0) { if (rc) { CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d", rc = 0; csid_hw->hw_intf->hw_idx, } else { reset_path, rc); CAM_ERR(CAM_ISP, "CSID:%d RDI%d reset fail", if (rc == 0) csid_hw->hw_intf->hw_idx, reset_path, rc); rc = -ETIMEDOUT; rc = -ETIMEDOUT; } } Loading Loading @@ -815,6 +813,7 @@ static int ais_ife_csid_enable_rdi_path( soc_info = &csid_hw->hw_info->soc_info; soc_info = &csid_hw->hw_info->soc_info; path_data = &csid_hw->rdi_cfg[id]; path_data = &csid_hw->rdi_cfg[id]; path_data->init_frame_drop = 1; path_data->sof_cnt = 0; path_data->sof_cnt = 0; /* Enable the required RDI interrupts */ /* Enable the required RDI interrupts */ Loading Loading @@ -1326,7 +1325,7 @@ static int ais_ife_csid_start(void *hw_priv, void *start_args, if (start_cmd->path >= csid_reg->cmn_reg->num_rdis || if (start_cmd->path >= csid_reg->cmn_reg->num_rdis || !csid_reg->rdi_reg[start_cmd->path]) { !csid_reg->rdi_reg[start_cmd->path]) { CAM_DBG(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", csid_hw->hw_intf->hw_idx, start_cmd->path); csid_hw->hw_intf->hw_idx, start_cmd->path); rc = -EINVAL; rc = -EINVAL; goto end; goto end; Loading Loading @@ -1367,7 +1366,7 @@ static int ais_ife_csid_stop(void *hw_priv, if (stop_cmd->path >= csid_reg->cmn_reg->num_rdis || if (stop_cmd->path >= csid_reg->cmn_reg->num_rdis || !csid_reg->rdi_reg[stop_cmd->path]) { !csid_reg->rdi_reg[stop_cmd->path]) { CAM_DBG(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", csid_hw->hw_intf->hw_idx, stop_cmd->path); csid_hw->hw_intf->hw_idx, stop_cmd->path); rc = -EINVAL; rc = -EINVAL; goto end; goto end; Loading Loading @@ -1677,6 +1676,7 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data) const struct ais_ife_csid_rdi_reg_offset *rdi_reg; const struct ais_ife_csid_rdi_reg_offset *rdi_reg; uint32_t i; uint32_t i; uint32_t val, val2; uint32_t val, val2; uint32_t warn_cnt = 0; bool fatal_err_detected = false; bool fatal_err_detected = false; uint32_t sof_irq_debug_en = 0; uint32_t sof_irq_debug_en = 0; unsigned long flags; unsigned long flags; Loading Loading @@ -1778,27 +1778,29 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data) } } if (irq_status[CSID_IRQ_STATUS_RX] & if (irq_status[CSID_IRQ_STATUS_RX] & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) { CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) { csid_hw->error_irq_count++; warn_cnt++; } } if (irq_status[CSID_IRQ_STATUS_RX] & if (irq_status[CSID_IRQ_STATUS_RX] & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) { CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) { csid_hw->error_irq_count++; warn_cnt++; } } if (irq_status[CSID_IRQ_STATUS_RX] & if (irq_status[CSID_IRQ_STATUS_RX] & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) { CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) { csid_hw->error_irq_count++; warn_cnt++; } } if (irq_status[CSID_IRQ_STATUS_RX] & if (irq_status[CSID_IRQ_STATUS_RX] & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) { CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) { csid_hw->error_irq_count++; warn_cnt++; } } } } csid_hw->error_irq_count += warn_cnt; if (csid_hw->error_irq_count > if (csid_hw->error_irq_count > AIS_IFE_CSID_MAX_IRQ_ERROR_COUNT) { AIS_IFE_CSID_MAX_IRQ_ERROR_COUNT) { fatal_err_detected = true; fatal_err_detected = true; csid_hw->error_irq_count = 0; csid_hw->error_irq_count = 0; } else if (csid_hw->error_irq_count) { } else if (warn_cnt) { uint64_t timestamp; uint64_t timestamp; timestamp = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); timestamp = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); Loading Loading @@ -1951,18 +1953,20 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data) (path_data->init_frame_drop) && (path_data->init_frame_drop) && (path_data->state == (path_data->state == AIS_ISP_RESOURCE_STATE_STREAMING)) { AIS_ISP_RESOURCE_STATE_STREAMING)) { path_data[i].sof_cnt++; path_data->sof_cnt++; CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP, "CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d", "CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d", csid_hw->hw_intf->hw_idx, i, csid_hw->hw_intf->hw_idx, i, path_data[i].sof_cnt, path_data->sof_cnt, path_data->init_frame_drop); path_data->init_frame_drop); if (path_data[i].sof_cnt == if (path_data->sof_cnt == path_data->init_frame_drop) { path_data->init_frame_drop) { cam_io_w_mb(AIS_CSID_RESUME_AT_FRAME_BOUNDARY, cam_io_w_mb(AIS_CSID_RESUME_AT_FRAME_BOUNDARY, soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base + rdi_reg->csid_rdi_ctrl_addr); rdi_reg->csid_rdi_ctrl_addr); path_data->init_frame_drop = 0; if (!(csid_hw->csid_debug & if (!(csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)) { CSID_DEBUG_ENABLE_SOF_IRQ)) { val = cam_io_r_mb( val = cam_io_r_mb( Loading
drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c +67 −31 Original line number Original line Diff line number Diff line Loading @@ -99,7 +99,7 @@ static int ais_vfe_bus_hw_init(struct ais_vfe_hw_core_info *core_info) cam_io_w_mb(core_info->irq_mask0, cam_io_w_mb(core_info->irq_mask0, core_info->mem_base + AIS_VFE_IRQ_MASK0); core_info->mem_base + AIS_VFE_IRQ_MASK0); cam_io_w_mb(0x7800, cam_io_w_mb(0x7801, core_info->mem_base + bus_hw_irq_regs[0].mask_reg_offset); core_info->mem_base + bus_hw_irq_regs[0].mask_reg_offset); cam_io_w_mb(0x0, cam_io_w_mb(0x0, core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset); core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset); Loading Loading @@ -220,7 +220,8 @@ static int ais_vfe_reset(void *hw_priv, CAM_DBG(CAM_ISP, "waiting for vfe reset complete"); CAM_DBG(CAM_ISP, "waiting for vfe reset complete"); /* Wait for Completion or Timeout of 500ms */ /* Wait for Completion or Timeout of 500ms */ rc = wait_for_completion_timeout(&vfe_hw->hw_complete, 500); rc = wait_for_completion_timeout(&vfe_hw->hw_complete, msecs_to_jiffies(500)); if (rc) { if (rc) { rc = 0; rc = 0; } else { } else { Loading Loading @@ -622,17 +623,28 @@ int ais_vfe_stop(void *hw_priv, void *stop_args, uint32_t arg_size) rdi_path->state = AIS_ISP_RESOURCE_STATE_INIT_HW; rdi_path->state = AIS_ISP_RESOURCE_STATE_INIT_HW; core_info->bus_wr_mask1 &= ~(1 << stop_cmd->path); cam_io_w_mb(core_info->bus_wr_mask1, core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset); /* Disable WM and reg-update */ /* Disable WM and reg-update */ cam_io_w_mb(0x0, core_info->mem_base + client_regs->cfg); cam_io_w_mb(0x0, core_info->mem_base + client_regs->cfg); cam_io_w_mb(AIS_VFE_REGUP_RDI_ALL, core_info->mem_base + cam_io_w_mb(AIS_VFE_REGUP_RDI_ALL, core_info->mem_base + top_hw_info->common_reg->reg_update_cmd); top_hw_info->common_reg->reg_update_cmd); /* issue bus wr reset and wait for reset ack */ reinit_completion(&vfe_hw->hw_complete); cam_io_w_mb((1 << stop_cmd->path), core_info->mem_base + cam_io_w_mb((1 << stop_cmd->path), core_info->mem_base + bus_hw_info->common_reg.sw_reset); bus_hw_info->common_reg.sw_reset); core_info->bus_wr_mask1 &= ~(1 << stop_cmd->path); /* Wait for completion or timeout of 50ms */ cam_io_w_mb(core_info->bus_wr_mask1, rc = wait_for_completion_timeout(&vfe_hw->hw_complete, core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset); msecs_to_jiffies(50)); if (rc) rc = 0; else CAM_WARN(CAM_ISP, "Reset Bus WR timeout"); ais_clear_rdi_path(rdi_path); ais_clear_rdi_path(rdi_path); Loading Loading @@ -896,7 +908,8 @@ static int ais_vfe_handle_error( static void ais_vfe_bus_handle_client_frame_done( static void ais_vfe_bus_handle_client_frame_done( struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_core_info *core_info, enum ais_ife_output_path_id path) enum ais_ife_output_path_id path, uint32_t last_addr) { { struct ais_vfe_rdi_output *rdi_path = NULL; struct ais_vfe_rdi_output *rdi_path = NULL; struct ais_vfe_buffer_t *vfe_buf = NULL; struct ais_vfe_buffer_t *vfe_buf = NULL; Loading Loading @@ -925,7 +938,7 @@ static void ais_vfe_bus_handle_client_frame_done( CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d DQ %d (0x%x) FIFO:%d|0x%x", CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d DQ %d (0x%x) FIFO:%d|0x%x", core_info->vfe_idx, path, core_info->vfe_idx, path, vfe_buf->bufIdx, vfe_buf->iova_addr, vfe_buf->bufIdx, vfe_buf->iova_addr, rdi_path->num_buffer_hw_q, rdi_path->last_addr); rdi_path->num_buffer_hw_q, last_addr); core_info->event.type = AIS_IFE_MSG_FRAME_DONE; core_info->event.type = AIS_IFE_MSG_FRAME_DONE; core_info->event.path = path; core_info->event.path = path; Loading @@ -937,15 +950,18 @@ static void ais_vfe_bus_handle_client_frame_done( core_info->event_cb(core_info->event_cb_priv, core_info->event_cb(core_info->event_cb_priv, &core_info->event); &core_info->event); if (rdi_path->last_addr == vfe_buf->iova_addr) if (last_addr == vfe_buf->iova_addr) last_addr_match = true; last_addr_match = true; else CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr", core_info->vfe_idx, vfe_buf->bufIdx); list_add_tail(&vfe_buf->list, &rdi_path->free_buffer_list); list_add_tail(&vfe_buf->list, &rdi_path->free_buffer_list); } } if (!last_addr_match) if (!last_addr_match) CAM_ERR(CAM_ISP, "IFE%d BUF| RDI%d NO MATCH addr 0x%x", CAM_ERR(CAM_ISP, "IFE%d BUF| RDI%d NO MATCH addr 0x%x", core_info->vfe_idx, path, rdi_path->last_addr); core_info->vfe_idx, path, last_addr); ais_vfe_queue_to_hw(core_info, path); ais_vfe_queue_to_hw(core_info, path); Loading @@ -954,9 +970,10 @@ static void ais_vfe_bus_handle_client_frame_done( static int ais_vfe_bus_handle_frame_done( static int ais_vfe_bus_handle_frame_done( struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_core_info *core_info, uint32_t client_mask) struct ais_vfe_hw_work_data *work_data) { { struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[0]; struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[0]; uint32_t client_mask = work_data->bus_wr_status[1]; uint32_t client; uint32_t client; int rc = 0; int rc = 0; Loading @@ -971,19 +988,18 @@ static int ais_vfe_bus_handle_frame_done( if (client_mask & (0x1 << client)) { if (client_mask & (0x1 << client)) { //process frame done //process frame done ais_vfe_bus_handle_client_frame_done(core_info, client); ais_vfe_bus_handle_client_frame_done(core_info, client, work_data->last_addr[client]); } } } } return rc; return rc; } } static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw, static void ais_vfe_irq_fill_bus_wr_status( struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_work_data *work_data) struct ais_vfe_hw_work_data *work_data) { { int rc = 0; uint32_t vfe_bus_status[3] = {}; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_irq_register_set *bus_hw_irq_regs = NULL; struct ais_irq_register_set *bus_hw_irq_regs = NULL; struct ais_vfe_bus_ver2_reg_offset_bus_client *client_regs = NULL; struct ais_vfe_bus_ver2_reg_offset_bus_client *client_regs = NULL; Loading @@ -993,53 +1009,72 @@ static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw, bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set; bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set; client_regs = &bus_hw_info->bus_client_reg[client]; client_regs = &bus_hw_info->bus_client_reg[client]; vfe_bus_status[0] = cam_io_r_mb(core_info->mem_base + work_data->bus_wr_status[0] = cam_io_r_mb(core_info->mem_base + bus_hw_irq_regs[0].status_reg_offset); bus_hw_irq_regs[0].status_reg_offset); vfe_bus_status[1] = cam_io_r_mb(core_info->mem_base + work_data->bus_wr_status[1] = cam_io_r_mb(core_info->mem_base + bus_hw_irq_regs[1].status_reg_offset); bus_hw_irq_regs[1].status_reg_offset); vfe_bus_status[2] = cam_io_r_mb(core_info->mem_base + work_data->bus_wr_status[2] = cam_io_r_mb(core_info->mem_base + bus_hw_irq_regs[2].status_reg_offset); bus_hw_irq_regs[2].status_reg_offset); if (vfe_bus_status[1]) { if (work_data->bus_wr_status[1]) { struct ais_vfe_rdi_output *p_rdi; struct ais_vfe_rdi_output *p_rdi; for (client = 0 ; client < AIS_IFE_PATH_MAX; client++) { for (client = 0 ; client < AIS_IFE_PATH_MAX; client++) { if (vfe_bus_status[1] & (0x1 << client)) { if (work_data->bus_wr_status[1] & (0x1 << client)) { p_rdi = &core_info->rdi_out[client]; p_rdi = &core_info->rdi_out[client]; client_regs = client_regs = &bus_hw_info->bus_client_reg[client]; &bus_hw_info->bus_client_reg[client]; p_rdi->last_addr = cam_io_r( work_data->last_addr[client] = cam_io_r( core_info->mem_base + core_info->mem_base + client_regs->status0); client_regs->status0); } } } } } } cam_io_w(vfe_bus_status[0], core_info->mem_base + cam_io_w(work_data->bus_wr_status[0], core_info->mem_base + bus_hw_irq_regs[0].clear_reg_offset); bus_hw_irq_regs[0].clear_reg_offset); cam_io_w(vfe_bus_status[1], core_info->mem_base + cam_io_w(work_data->bus_wr_status[1], core_info->mem_base + bus_hw_irq_regs[1].clear_reg_offset); bus_hw_irq_regs[1].clear_reg_offset); cam_io_w(vfe_bus_status[2], core_info->mem_base + cam_io_w(work_data->bus_wr_status[2], core_info->mem_base + bus_hw_irq_regs[2].clear_reg_offset); bus_hw_irq_regs[2].clear_reg_offset); cam_io_w_mb(0x1, core_info->mem_base + cam_io_w_mb(0x1, core_info->mem_base + bus_hw_info->common_reg.irq_reg_info.global_clear_offset); bus_hw_info->common_reg.irq_reg_info.global_clear_offset); } static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw, struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_work_data *work_data) { int rc = 0; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_irq_register_set *bus_hw_irq_regs = NULL; struct ais_vfe_bus_ver2_reg_offset_bus_client *client_regs = NULL; uint32_t client = 0; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set; client_regs = &bus_hw_info->bus_client_reg[client]; CAM_DBG(CAM_ISP, "VFE%d BUS status 0x%x 0x%x 0x%x", core_info->vfe_idx, CAM_DBG(CAM_ISP, "VFE%d BUS status 0x%x 0x%x 0x%x", core_info->vfe_idx, vfe_bus_status[0], vfe_bus_status[1], vfe_bus_status[2]); work_data->bus_wr_status[0], work_data->bus_wr_status[1], work_data->bus_wr_status[2]); if (vfe_bus_status[1]) if (work_data->bus_wr_status[1]) ais_vfe_bus_handle_frame_done(core_info, vfe_bus_status[1]); ais_vfe_bus_handle_frame_done(core_info, work_data); if (vfe_bus_status[0] & 0x7800) { if (work_data->bus_wr_status[0] & 0x7800) { CAM_ERR(CAM_ISP, "VFE%d: WR BUS error occurred status = 0x%x", CAM_ERR(CAM_ISP, "VFE%d: WR BUS error occurred status = 0x%x", core_info->vfe_idx, vfe_bus_status[0]); core_info->vfe_idx, work_data->bus_wr_status[0]); work_data->path = (vfe_bus_status[0] >> 11) & 0xF; work_data->path = (work_data->bus_wr_status[0] >> 11) & 0xF; rc = ais_vfe_handle_error(core_info, work_data); rc = ais_vfe_handle_error(core_info, work_data); } } if (vfe_bus_status[0] & 0x1) { if (work_data->bus_wr_status[0] & 0x1) { CAM_INFO(CAM_ISP, "VFE%d: WR BUS reset completed", CAM_INFO(CAM_ISP, "VFE%d: WR BUS reset completed", core_info->vfe_idx); core_info->vfe_idx); complete(&vfe_hw->hw_complete); } } return rc; return rc; Loading Loading @@ -1194,6 +1229,7 @@ irqreturn_t ais_vfe_irq(int irq_num, void *data) //BUS_WR IRQ //BUS_WR IRQ CAM_DBG(CAM_ISP, "IFE%d BUS_WR", core_info->vfe_idx); CAM_DBG(CAM_ISP, "IFE%d BUS_WR", core_info->vfe_idx); work_data.evt_type = AIS_VFE_HW_IRQ_EVENT_BUS_WR; work_data.evt_type = AIS_VFE_HW_IRQ_EVENT_BUS_WR; ais_vfe_irq_fill_bus_wr_status(core_info, &work_data); ais_vfe_dispatch_irq(vfe_hw, &work_data); ais_vfe_dispatch_irq(vfe_hw, &work_data); } } if (ife_status[1]) { if (ife_status[1]) { Loading
drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,8 @@ struct ais_vfe_hw_work_data { enum ais_vfe_hw_irq_event evt_type; enum ais_vfe_hw_irq_event evt_type; uint32_t path; uint32_t path; uint64_t ts; uint64_t ts; uint32_t bus_wr_status[3]; uint32_t last_addr[AIS_IFE_PATH_MAX]; struct ais_ife_rdi_timestamps ts_hw[AIS_IFE_PATH_MAX]; struct ais_ife_rdi_timestamps ts_hw[AIS_IFE_PATH_MAX]; }; }; Loading Loading @@ -93,7 +95,6 @@ struct ais_vfe_rdi_output { struct list_head buffer_hw_q; struct list_head buffer_hw_q; struct list_head free_buffer_list; struct list_head free_buffer_list; uint32_t last_addr; uint64_t frame_cnt; uint64_t frame_cnt; uint64_t sof_ts; uint64_t sof_ts; uint64_t sof_hw_ts; uint64_t sof_hw_ts; Loading
drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +2 −1 Original line number Original line Diff line number Diff line Loading @@ -417,7 +417,8 @@ int cam_vfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size) reset_core_args, arg_size); reset_core_args, arg_size); CAM_DBG(CAM_ISP, "waiting for vfe reset complete"); CAM_DBG(CAM_ISP, "waiting for vfe reset complete"); /* Wait for Completion or Timeout of 500ms */ /* Wait for Completion or Timeout of 500ms */ rc = wait_for_completion_timeout(&vfe_hw->hw_complete, 500); rc = wait_for_completion_timeout(&vfe_hw->hw_complete, msecs_to_jiffies(500)); if (!rc) if (!rc) CAM_ERR(CAM_ISP, "Error! Reset Timeout"); CAM_ERR(CAM_ISP, "Error! Reset Timeout"); Loading