Loading drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.c +0 −4 Original line number Original line Diff line number Diff line Loading @@ -476,16 +476,12 @@ static int ais_ife_dev_cb(void *priv, struct ais_ife_event_data *evt_data) return -EINVAL; return -EINVAL; } } spin_lock_bh(&p_ife_dev->eventq_lock); /* Queue the event */ /* Queue the event */ memcpy(event.u.data, (void *)evt_data, sizeof(*evt_data)); memcpy(event.u.data, (void *)evt_data, sizeof(*evt_data)); event.id = V4L_EVENT_ID_AIS_IFE; event.id = V4L_EVENT_ID_AIS_IFE; event.type = V4L_EVENT_TYPE_AIS_IFE; event.type = V4L_EVENT_TYPE_AIS_IFE; v4l2_event_queue(p_ife_dev->cam_sd.sd.devnode, &event); v4l2_event_queue(p_ife_dev->cam_sd.sd.devnode, &event); spin_unlock_bh(&p_ife_dev->eventq_lock); return 0; return 0; } } Loading drivers/media/platform/msm/ais/ais_isp/include/ais_isp_hw.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -479,6 +479,7 @@ struct ais_ife_frame_msg { enum ais_ife_msg_type { enum ais_ife_msg_type { AIS_IFE_MSG_SOF, AIS_IFE_MSG_SOF, AIS_IFE_MSG_FRAME_DONE, AIS_IFE_MSG_FRAME_DONE, AIS_IFE_MSG_OUTPUT_WARNING, AIS_IFE_MSG_OUTPUT_ERROR, AIS_IFE_MSG_OUTPUT_ERROR, AIS_IFE_MSG_CSID_WARNING, AIS_IFE_MSG_CSID_WARNING, AIS_IFE_MSG_CSID_ERROR AIS_IFE_MSG_CSID_ERROR Loading drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c +301 −31 Original line number Original line Diff line number Diff line Loading @@ -52,9 +52,10 @@ #define AIS_VFE_REGUP_RDI_SHIFT 1 #define AIS_VFE_REGUP_RDI_SHIFT 1 #define AIS_VFE_REGUP_RDI_ALL 0x1E #define AIS_VFE_REGUP_RDI_ALL 0x1E /*VFE BUS DEFINITIONS*/ /*Allow max of 4 HW FIFO Q + 2 delayed buffers before error*/ #define MAX_NUM_BUF_HW_FIFOQ 4 #define MAX_NUM_BUF_SW_FIFOQ_ERR 6 /*VFE BUS DEFINITIONS*/ #define AIS_VFE_BUS_SET_DEBUG_REG 0x82 #define AIS_VFE_BUS_SET_DEBUG_REG 0x82 #define AIS_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01 #define AIS_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01 Loading @@ -72,8 +73,6 @@ static void ais_clear_rdi_path(struct ais_vfe_rdi_output *rdi_path) int i; int i; rdi_path->frame_cnt = 0; rdi_path->frame_cnt = 0; rdi_path->sof_ts = 0; rdi_path->sof_hw_ts = 0; rdi_path->num_buffer_hw_q = 0; rdi_path->num_buffer_hw_q = 0; INIT_LIST_HEAD(&rdi_path->buffer_q); INIT_LIST_HEAD(&rdi_path->buffer_q); Loading @@ -84,6 +83,17 @@ static void ais_clear_rdi_path(struct ais_vfe_rdi_output *rdi_path) list_add_tail(&rdi_path->buffers[i].list, list_add_tail(&rdi_path->buffers[i].list, &rdi_path->free_buffer_list); &rdi_path->free_buffer_list); } } memset(&rdi_path->last_sof_info, 0, sizeof(rdi_path->last_sof_info)); rdi_path->num_sof_info_q = 0; INIT_LIST_HEAD(&rdi_path->sof_info_q); INIT_LIST_HEAD(&rdi_path->free_sof_info_list); for (i = 0; i < AIS_VFE_MAX_SOF_INFO; i++) { INIT_LIST_HEAD(&rdi_path->sof_info[i].list); list_add_tail(&rdi_path->sof_info[i].list, &rdi_path->free_sof_info_list); } } } static int ais_vfe_bus_hw_init(struct ais_vfe_hw_core_info *core_info) static int ais_vfe_bus_hw_init(struct ais_vfe_hw_core_info *core_info) Loading Loading @@ -664,19 +674,26 @@ int ais_vfe_write(void *hw_priv, void *write_args, uint32_t arg_size) return -EPERM; return -EPERM; } } static void ais_vfe_queue_to_hw(struct ais_vfe_hw_core_info *core_info, static void ais_vfe_q_bufs_to_hw(struct ais_vfe_hw_core_info *core_info, enum ais_ife_output_path_id path) enum ais_ife_output_path_id path) { { 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; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = 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; uint32_t fifo_status = 0; bool is_full = false; rdi_path = &core_info->rdi_out[path]; rdi_path = &core_info->rdi_out[path]; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; client_regs = &bus_hw_info->bus_client_reg[path]; client_regs = &bus_hw_info->bus_client_reg[path]; while (rdi_path->num_buffer_hw_q < MAX_NUM_BUF_HW_FIFOQ) { fifo_status = cam_io_r_mb(core_info->mem_base + bus_hw_info->common_reg.addr_fifo_status); is_full = fifo_status & (1 << path); while (!is_full) { if (list_empty(&rdi_path->buffer_q)) if (list_empty(&rdi_path->buffer_q)) break; break; Loading @@ -684,7 +701,7 @@ static void ais_vfe_queue_to_hw(struct ais_vfe_hw_core_info *core_info, struct ais_vfe_buffer_t, list); struct ais_vfe_buffer_t, list); list_del_init(&vfe_buf->list); list_del_init(&vfe_buf->list); CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d Q %d(0x%x) FIFO:%d", CAM_DBG(CAM_ISP, "IFE%d|RDI%d: Q %d(0x%x) FIFO:%d", 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->num_buffer_hw_q); Loading @@ -694,7 +711,15 @@ static void ais_vfe_queue_to_hw(struct ais_vfe_hw_core_info *core_info, list_add_tail(&vfe_buf->list, &rdi_path->buffer_hw_q); list_add_tail(&vfe_buf->list, &rdi_path->buffer_hw_q); ++rdi_path->num_buffer_hw_q; ++rdi_path->num_buffer_hw_q; fifo_status = cam_io_r_mb(core_info->mem_base + bus_hw_info->common_reg.addr_fifo_status); is_full = fifo_status & (1 << path); } } if (rdi_path->num_buffer_hw_q > MAX_NUM_BUF_SW_FIFOQ_ERR) CAM_WARN(CAM_ISP, "Excessive number of buffers in SW FIFO (%d)", rdi_path->num_buffer_hw_q); } } Loading Loading @@ -767,7 +792,10 @@ static int ais_vfe_cmd_enq_buf(struct ais_vfe_hw_core_info *core_info, spin_lock(&rdi_path->buffer_lock); spin_lock(&rdi_path->buffer_lock); list_add_tail(&vfe_buf->list, &rdi_path->buffer_q); list_add_tail(&vfe_buf->list, &rdi_path->buffer_q); ais_vfe_queue_to_hw(core_info, enq_buf->path); if (rdi_path->state < AIS_ISP_RESOURCE_STATE_STREAMING) ais_vfe_q_bufs_to_hw(core_info, enq_buf->path); spin_unlock(&rdi_path->buffer_lock); spin_unlock(&rdi_path->buffer_lock); } } Loading Loading @@ -816,6 +844,181 @@ int ais_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, return rc; return rc; } } static uint8_t ais_vfe_get_num_missed_sof( uint64_t cur_sof, uint64_t prev_sof, uint64_t last_sof, uint64_t ts_delta) { uint8_t miss_sof = 0; if (prev_sof == last_sof) { miss_sof = 0; } else if (prev_sof < last_sof) { //rollover case miss_sof = (int)(((U64_MAX - last_sof) + prev_sof + 1 + ts_delta/2) / ts_delta); } else { miss_sof = (int)((prev_sof - last_sof + ts_delta/2) / ts_delta); } return miss_sof; } static int ais_vfe_q_sof(struct ais_vfe_hw_core_info *core_info, enum ais_ife_output_path_id path, struct ais_sof_info_t *p_sof) { struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[path]; struct ais_sof_info_t *p_sof_info = NULL; int rc = 0; if (!list_empty(&p_rdi->free_sof_info_list)) { p_sof_info = list_first_entry(&p_rdi->free_sof_info_list, struct ais_sof_info_t, list); list_del_init(&p_sof_info->list); p_sof_info->frame_cnt = p_sof->frame_cnt; p_sof_info->sof_ts = p_sof->sof_ts; p_sof_info->cur_sof_hw_ts = p_sof->cur_sof_hw_ts; p_sof_info->prev_sof_hw_ts = p_sof->prev_sof_hw_ts; list_add_tail(&p_sof_info->list, &p_rdi->sof_info_q); p_rdi->num_sof_info_q++; CAM_DBG(CAM_ISP, "I%d|R%d|F%llu: sof %llu", core_info->vfe_idx, path, p_rdi->frame_cnt, p_sof_info->cur_sof_hw_ts); } else { rc = -1; CAM_ERR(CAM_ISP, "I%d|R%d|F%llu: free timestamp empty (%d)", core_info->vfe_idx, path, p_rdi->frame_cnt, p_rdi->num_buffer_hw_q); } return rc; } static void ais_vfe_handle_sof_rdi(struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_work_data *work_data, enum ais_ife_output_path_id path) { struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[path]; uint64_t cur_sof_hw_ts = work_data->ts_hw[path].cur_sof_ts; uint64_t prev_sof_hw_ts = work_data->ts_hw[path].prev_sof_ts; p_rdi->frame_cnt++; if (p_rdi->num_buffer_hw_q) { struct ais_sof_info_t sof = {}; uint64_t ts_delta; uint8_t miss_sof = 0; if (cur_sof_hw_ts < prev_sof_hw_ts) ts_delta = cur_sof_hw_ts + (U64_MAX - prev_sof_hw_ts); else ts_delta = cur_sof_hw_ts - prev_sof_hw_ts; //check any missing SOFs if (p_rdi->frame_cnt > 1) { if (ts_delta == 0) { CAM_ERR(CAM_ISP, "IFE%d RDI%d ts_delta is 0", core_info->vfe_idx, path); } else { miss_sof = ais_vfe_get_num_missed_sof( cur_sof_hw_ts, prev_sof_hw_ts, p_rdi->last_sof_info.cur_sof_hw_ts, ts_delta); } } if (p_rdi->frame_cnt == 1 && prev_sof_hw_ts != 0) { //enq missed first frame sof.sof_ts = work_data->ts; sof.cur_sof_hw_ts = prev_sof_hw_ts; sof.frame_cnt = p_rdi->frame_cnt++; ais_vfe_q_sof(core_info, path, &sof); } else if (miss_sof > 0) { if (miss_sof > 1) { int i = 0; int miss_idx = miss_sof - 1; for (i = 0; i < (miss_sof - 1); i++) { sof.sof_ts = work_data->ts; sof.cur_sof_hw_ts = prev_sof_hw_ts - (ts_delta * miss_idx); sof.frame_cnt = p_rdi->frame_cnt++; ais_vfe_q_sof(core_info, path, &sof); miss_idx--; } } //enq prev sof.sof_ts = work_data->ts; sof.cur_sof_hw_ts = prev_sof_hw_ts; sof.frame_cnt = p_rdi->frame_cnt++; ais_vfe_q_sof(core_info, path, &sof); } //enq curr sof.sof_ts = work_data->ts; sof.cur_sof_hw_ts = prev_sof_hw_ts; sof.frame_cnt = p_rdi->frame_cnt; ais_vfe_q_sof(core_info, path, &sof); } else { CAM_DBG(CAM_ISP, "I%d R%d Flush SOF (%d) HW Q empty", core_info->vfe_idx, path, p_rdi->num_sof_info_q); if (p_rdi->num_sof_info_q) { struct ais_sof_info_t *p_sof_info; while (!list_empty(&p_rdi->sof_info_q)) { p_sof_info = list_first_entry( &p_rdi->sof_info_q, struct ais_sof_info_t, list); list_del_init(&p_sof_info->list); list_add_tail(&p_sof_info->list, &p_rdi->free_sof_info_list); } p_rdi->num_sof_info_q = 0; } //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; core_info->event.path = path; core_info->event.u.err_msg.reserved = 0; core_info->event_cb(core_info->event_cb_priv, &core_info->event); } p_rdi->last_sof_info.cur_sof_hw_ts = cur_sof_hw_ts; //send sof only for current frame core_info->event.type = AIS_IFE_MSG_SOF; core_info->event.path = path; core_info->event.u.sof_msg.frame_id = p_rdi->frame_cnt; core_info->event.u.sof_msg.hw_ts = cur_sof_hw_ts; core_info->event_cb(core_info->event_cb_priv, &core_info->event); } static int ais_vfe_handle_sof( static int ais_vfe_handle_sof( 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) Loading @@ -836,17 +1039,12 @@ static int ais_vfe_handle_sof( if (p_rdi->state != AIS_ISP_RESOURCE_STATE_STREAMING) if (p_rdi->state != AIS_ISP_RESOURCE_STATE_STREAMING) continue; continue; p_rdi->frame_cnt++; ais_vfe_handle_sof_rdi(core_info, work_data, path); p_rdi->sof_ts = work_data->ts; p_rdi->sof_hw_ts = work_data->ts_hw[path].cur_sof_ts; core_info->event.type = AIS_IFE_MSG_SOF; //enq buffers core_info->event.path = path; spin_lock_bh(&p_rdi->buffer_lock); core_info->event.u.sof_msg.frame_id = p_rdi->frame_cnt; ais_vfe_q_bufs_to_hw(core_info, path); core_info->event.u.sof_msg.hw_ts = p_rdi->sof_ts; spin_unlock_bh(&p_rdi->buffer_lock); core_info->event_cb(core_info->event_cb_priv, &core_info->event); } } return rc; return rc; Loading Loading @@ -914,19 +1112,32 @@ static void ais_vfe_bus_handle_client_frame_done( 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; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; uint64_t frame_cnt; uint64_t sof_ts; uint64_t cur_sof_hw_ts; bool last_addr_match = false; bool last_addr_match = false; CAM_DBG(CAM_ISP, "Frame Done Client %d", path); CAM_DBG(CAM_ISP, "I%d|R%d last_addr 0x%x", core_info->vfe_idx, path, last_addr); if (last_addr == 0) { CAM_ERR(CAM_ISP, "I%d|R%d null last_addr", core_info->vfe_idx, path); return; } rdi_path = &core_info->rdi_out[path]; rdi_path = &core_info->rdi_out[path]; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; spin_lock_bh(&rdi_path->buffer_lock); core_info->event.type = AIS_IFE_MSG_FRAME_DONE; core_info->event.path = path; while (rdi_path->num_buffer_hw_q && !last_addr_match) { while (rdi_path->num_buffer_hw_q && !last_addr_match) { struct ais_sof_info_t *p_sof_info = NULL; if (list_empty(&rdi_path->buffer_hw_q)) { if (list_empty(&rdi_path->buffer_hw_q)) { CAM_ERR(CAM_ISP, "Received RDI%d FD while SW Q empty", CAM_DBG(CAM_ISP, "I%d|R%d: FD while HW Q empty", path); core_info->vfe_idx, path); break; break; } } Loading @@ -935,17 +1146,39 @@ static void ais_vfe_bus_handle_client_frame_done( list_del_init(&vfe_buf->list); list_del_init(&vfe_buf->list); --rdi_path->num_buffer_hw_q; --rdi_path->num_buffer_hw_q; CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d DQ %d (0x%x) FIFO:%d|0x%x", CAM_DBG(CAM_ISP, "I%d|R%d BUF 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, last_addr); rdi_path->num_buffer_hw_q, last_addr); core_info->event.type = AIS_IFE_MSG_FRAME_DONE; if (!list_empty(&rdi_path->sof_info_q)) { core_info->event.path = path; p_sof_info = list_first_entry(&rdi_path->sof_info_q, core_info->event.u.frame_msg.frame_id = rdi_path->frame_cnt; struct ais_sof_info_t, list); list_del_init(&p_sof_info->list); rdi_path->num_sof_info_q--; } else CAM_ERR(CAM_ISP, "I%d|R%d: SOF info Q is empty", core_info->vfe_idx, path); if (p_sof_info) { frame_cnt = p_sof_info->frame_cnt; sof_ts = p_sof_info->sof_ts; cur_sof_hw_ts = p_sof_info->cur_sof_hw_ts; list_add_tail(&p_sof_info->list, &rdi_path->free_sof_info_list); } else { frame_cnt = sof_ts = cur_sof_hw_ts = 0; } CAM_DBG(CAM_ISP, "I%d|R%d|F%llu: si [%llu, %llu, %llu]", core_info->vfe_idx, path, frame_cnt, sof_ts, cur_sof_hw_ts); core_info->event.u.frame_msg.frame_id = frame_cnt; core_info->event.u.frame_msg.buf_idx = vfe_buf->bufIdx; core_info->event.u.frame_msg.buf_idx = vfe_buf->bufIdx; core_info->event.u.frame_msg.ts = rdi_path->sof_ts; core_info->event.u.frame_msg.ts = sof_ts; core_info->event.u.frame_msg.hw_ts = rdi_path->sof_hw_ts; core_info->event.u.frame_msg.hw_ts = cur_sof_hw_ts; core_info->event_cb(core_info->event_cb_priv, core_info->event_cb(core_info->event_cb_priv, &core_info->event); &core_info->event); Loading @@ -955,15 +1188,52 @@ static void ais_vfe_bus_handle_client_frame_done( else else CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr", CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr", core_info->vfe_idx, vfe_buf->bufIdx); 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, last_addr); core_info->vfe_idx, path, last_addr); ais_vfe_queue_to_hw(core_info, path); //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; core_info->event.path = path; core_info->event.u.err_msg.reserved = 1; core_info->event_cb(core_info->event_cb_priv, &core_info->event); } /* Flush SOF info Q if HW Buffer Q is empty */ if (rdi_path->num_buffer_hw_q == 0) { struct ais_sof_info_t *p_sof_info = NULL; CAM_DBG(CAM_ISP, "I%d|R%d|F%llu: Flush SOF (%d) HW Q empty", core_info->vfe_idx, path, frame_cnt, rdi_path->num_sof_info_q); while (!list_empty(&rdi_path->sof_info_q)) { p_sof_info = list_first_entry(&rdi_path->sof_info_q, struct ais_sof_info_t, list); list_del_init(&p_sof_info->list); list_add_tail(&p_sof_info->list, &rdi_path->free_sof_info_list); } rdi_path->num_sof_info_q = 0; //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; core_info->event.path = path; core_info->event.u.err_msg.reserved = 0; core_info->event_cb(core_info->event_cb_priv, &core_info->event); } spin_lock_bh(&rdi_path->buffer_lock); ais_vfe_q_bufs_to_hw(core_info, path); spin_unlock_bh(&rdi_path->buffer_lock); spin_unlock_bh(&rdi_path->buffer_lock); } } Loading drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.h +16 −3 Original line number Original line Diff line number Diff line Loading @@ -20,8 +20,9 @@ #include "ais_vfe_bus_ver2.h" #include "ais_vfe_bus_ver2.h" #include "ais_vfe_top_ver2.h" #include "ais_vfe_top_ver2.h" #define AIS_VFE_WORKQ_NUM_TASK 16 #define AIS_VFE_WORKQ_NUM_TASK 20 #define AIS_VFE_MAX_BUF 12 #define AIS_VFE_MAX_BUF 12 #define AIS_VFE_MAX_SOF_INFO 8 enum ais_vfe_hw_irq_event { enum ais_vfe_hw_irq_event { AIS_VFE_HW_IRQ_EVENT_SOF, AIS_VFE_HW_IRQ_EVENT_SOF, Loading Loading @@ -83,6 +84,14 @@ struct ais_vfe_buffer_t { uint32_t bufIdx; uint32_t bufIdx; }; }; struct ais_sof_info_t { struct list_head list; uint64_t frame_cnt; uint64_t sof_ts; uint64_t cur_sof_hw_ts; uint64_t prev_sof_hw_ts; }; struct ais_vfe_rdi_output { struct ais_vfe_rdi_output { enum ais_isp_resource_state state; enum ais_isp_resource_state state; Loading @@ -96,8 +105,12 @@ struct ais_vfe_rdi_output { struct list_head free_buffer_list; struct list_head free_buffer_list; uint64_t frame_cnt; uint64_t frame_cnt; uint64_t sof_ts; uint64_t sof_hw_ts; uint8_t num_sof_info_q; struct ais_sof_info_t sof_info[AIS_VFE_MAX_SOF_INFO]; struct list_head sof_info_q; struct list_head free_sof_info_list; struct ais_sof_info_t last_sof_info; }; }; struct ais_vfe_hw_core_info { struct ais_vfe_hw_core_info { Loading drivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe17x/ais_vfe170.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -429,6 +429,7 @@ static struct ais_vfe_bus_ver2_hw_info vfe170_bus_hw_info = { .addr_sync_cfg = 0x0000207C, .addr_sync_cfg = 0x0000207C, .addr_sync_frame_hdr = 0x00002080, .addr_sync_frame_hdr = 0x00002080, .addr_sync_no_sync = 0x00002084, .addr_sync_no_sync = 0x00002084, .addr_fifo_status = 0x000020A8, .debug_status_cfg = 0x0000226C, .debug_status_cfg = 0x0000226C, .debug_status_0 = 0x00002270, .debug_status_0 = 0x00002270, }, }, Loading Loading
drivers/media/platform/msm/ais/ais_isp/ais_ife_dev.c +0 −4 Original line number Original line Diff line number Diff line Loading @@ -476,16 +476,12 @@ static int ais_ife_dev_cb(void *priv, struct ais_ife_event_data *evt_data) return -EINVAL; return -EINVAL; } } spin_lock_bh(&p_ife_dev->eventq_lock); /* Queue the event */ /* Queue the event */ memcpy(event.u.data, (void *)evt_data, sizeof(*evt_data)); memcpy(event.u.data, (void *)evt_data, sizeof(*evt_data)); event.id = V4L_EVENT_ID_AIS_IFE; event.id = V4L_EVENT_ID_AIS_IFE; event.type = V4L_EVENT_TYPE_AIS_IFE; event.type = V4L_EVENT_TYPE_AIS_IFE; v4l2_event_queue(p_ife_dev->cam_sd.sd.devnode, &event); v4l2_event_queue(p_ife_dev->cam_sd.sd.devnode, &event); spin_unlock_bh(&p_ife_dev->eventq_lock); return 0; return 0; } } Loading
drivers/media/platform/msm/ais/ais_isp/include/ais_isp_hw.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -479,6 +479,7 @@ struct ais_ife_frame_msg { enum ais_ife_msg_type { enum ais_ife_msg_type { AIS_IFE_MSG_SOF, AIS_IFE_MSG_SOF, AIS_IFE_MSG_FRAME_DONE, AIS_IFE_MSG_FRAME_DONE, AIS_IFE_MSG_OUTPUT_WARNING, AIS_IFE_MSG_OUTPUT_ERROR, AIS_IFE_MSG_OUTPUT_ERROR, AIS_IFE_MSG_CSID_WARNING, AIS_IFE_MSG_CSID_WARNING, AIS_IFE_MSG_CSID_ERROR AIS_IFE_MSG_CSID_ERROR Loading
drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.c +301 −31 Original line number Original line Diff line number Diff line Loading @@ -52,9 +52,10 @@ #define AIS_VFE_REGUP_RDI_SHIFT 1 #define AIS_VFE_REGUP_RDI_SHIFT 1 #define AIS_VFE_REGUP_RDI_ALL 0x1E #define AIS_VFE_REGUP_RDI_ALL 0x1E /*VFE BUS DEFINITIONS*/ /*Allow max of 4 HW FIFO Q + 2 delayed buffers before error*/ #define MAX_NUM_BUF_HW_FIFOQ 4 #define MAX_NUM_BUF_SW_FIFOQ_ERR 6 /*VFE BUS DEFINITIONS*/ #define AIS_VFE_BUS_SET_DEBUG_REG 0x82 #define AIS_VFE_BUS_SET_DEBUG_REG 0x82 #define AIS_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01 #define AIS_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01 Loading @@ -72,8 +73,6 @@ static void ais_clear_rdi_path(struct ais_vfe_rdi_output *rdi_path) int i; int i; rdi_path->frame_cnt = 0; rdi_path->frame_cnt = 0; rdi_path->sof_ts = 0; rdi_path->sof_hw_ts = 0; rdi_path->num_buffer_hw_q = 0; rdi_path->num_buffer_hw_q = 0; INIT_LIST_HEAD(&rdi_path->buffer_q); INIT_LIST_HEAD(&rdi_path->buffer_q); Loading @@ -84,6 +83,17 @@ static void ais_clear_rdi_path(struct ais_vfe_rdi_output *rdi_path) list_add_tail(&rdi_path->buffers[i].list, list_add_tail(&rdi_path->buffers[i].list, &rdi_path->free_buffer_list); &rdi_path->free_buffer_list); } } memset(&rdi_path->last_sof_info, 0, sizeof(rdi_path->last_sof_info)); rdi_path->num_sof_info_q = 0; INIT_LIST_HEAD(&rdi_path->sof_info_q); INIT_LIST_HEAD(&rdi_path->free_sof_info_list); for (i = 0; i < AIS_VFE_MAX_SOF_INFO; i++) { INIT_LIST_HEAD(&rdi_path->sof_info[i].list); list_add_tail(&rdi_path->sof_info[i].list, &rdi_path->free_sof_info_list); } } } static int ais_vfe_bus_hw_init(struct ais_vfe_hw_core_info *core_info) static int ais_vfe_bus_hw_init(struct ais_vfe_hw_core_info *core_info) Loading Loading @@ -664,19 +674,26 @@ int ais_vfe_write(void *hw_priv, void *write_args, uint32_t arg_size) return -EPERM; return -EPERM; } } static void ais_vfe_queue_to_hw(struct ais_vfe_hw_core_info *core_info, static void ais_vfe_q_bufs_to_hw(struct ais_vfe_hw_core_info *core_info, enum ais_ife_output_path_id path) enum ais_ife_output_path_id path) { { 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; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = 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; uint32_t fifo_status = 0; bool is_full = false; rdi_path = &core_info->rdi_out[path]; rdi_path = &core_info->rdi_out[path]; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; client_regs = &bus_hw_info->bus_client_reg[path]; client_regs = &bus_hw_info->bus_client_reg[path]; while (rdi_path->num_buffer_hw_q < MAX_NUM_BUF_HW_FIFOQ) { fifo_status = cam_io_r_mb(core_info->mem_base + bus_hw_info->common_reg.addr_fifo_status); is_full = fifo_status & (1 << path); while (!is_full) { if (list_empty(&rdi_path->buffer_q)) if (list_empty(&rdi_path->buffer_q)) break; break; Loading @@ -684,7 +701,7 @@ static void ais_vfe_queue_to_hw(struct ais_vfe_hw_core_info *core_info, struct ais_vfe_buffer_t, list); struct ais_vfe_buffer_t, list); list_del_init(&vfe_buf->list); list_del_init(&vfe_buf->list); CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d Q %d(0x%x) FIFO:%d", CAM_DBG(CAM_ISP, "IFE%d|RDI%d: Q %d(0x%x) FIFO:%d", 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->num_buffer_hw_q); Loading @@ -694,7 +711,15 @@ static void ais_vfe_queue_to_hw(struct ais_vfe_hw_core_info *core_info, list_add_tail(&vfe_buf->list, &rdi_path->buffer_hw_q); list_add_tail(&vfe_buf->list, &rdi_path->buffer_hw_q); ++rdi_path->num_buffer_hw_q; ++rdi_path->num_buffer_hw_q; fifo_status = cam_io_r_mb(core_info->mem_base + bus_hw_info->common_reg.addr_fifo_status); is_full = fifo_status & (1 << path); } } if (rdi_path->num_buffer_hw_q > MAX_NUM_BUF_SW_FIFOQ_ERR) CAM_WARN(CAM_ISP, "Excessive number of buffers in SW FIFO (%d)", rdi_path->num_buffer_hw_q); } } Loading Loading @@ -767,7 +792,10 @@ static int ais_vfe_cmd_enq_buf(struct ais_vfe_hw_core_info *core_info, spin_lock(&rdi_path->buffer_lock); spin_lock(&rdi_path->buffer_lock); list_add_tail(&vfe_buf->list, &rdi_path->buffer_q); list_add_tail(&vfe_buf->list, &rdi_path->buffer_q); ais_vfe_queue_to_hw(core_info, enq_buf->path); if (rdi_path->state < AIS_ISP_RESOURCE_STATE_STREAMING) ais_vfe_q_bufs_to_hw(core_info, enq_buf->path); spin_unlock(&rdi_path->buffer_lock); spin_unlock(&rdi_path->buffer_lock); } } Loading Loading @@ -816,6 +844,181 @@ int ais_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, return rc; return rc; } } static uint8_t ais_vfe_get_num_missed_sof( uint64_t cur_sof, uint64_t prev_sof, uint64_t last_sof, uint64_t ts_delta) { uint8_t miss_sof = 0; if (prev_sof == last_sof) { miss_sof = 0; } else if (prev_sof < last_sof) { //rollover case miss_sof = (int)(((U64_MAX - last_sof) + prev_sof + 1 + ts_delta/2) / ts_delta); } else { miss_sof = (int)((prev_sof - last_sof + ts_delta/2) / ts_delta); } return miss_sof; } static int ais_vfe_q_sof(struct ais_vfe_hw_core_info *core_info, enum ais_ife_output_path_id path, struct ais_sof_info_t *p_sof) { struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[path]; struct ais_sof_info_t *p_sof_info = NULL; int rc = 0; if (!list_empty(&p_rdi->free_sof_info_list)) { p_sof_info = list_first_entry(&p_rdi->free_sof_info_list, struct ais_sof_info_t, list); list_del_init(&p_sof_info->list); p_sof_info->frame_cnt = p_sof->frame_cnt; p_sof_info->sof_ts = p_sof->sof_ts; p_sof_info->cur_sof_hw_ts = p_sof->cur_sof_hw_ts; p_sof_info->prev_sof_hw_ts = p_sof->prev_sof_hw_ts; list_add_tail(&p_sof_info->list, &p_rdi->sof_info_q); p_rdi->num_sof_info_q++; CAM_DBG(CAM_ISP, "I%d|R%d|F%llu: sof %llu", core_info->vfe_idx, path, p_rdi->frame_cnt, p_sof_info->cur_sof_hw_ts); } else { rc = -1; CAM_ERR(CAM_ISP, "I%d|R%d|F%llu: free timestamp empty (%d)", core_info->vfe_idx, path, p_rdi->frame_cnt, p_rdi->num_buffer_hw_q); } return rc; } static void ais_vfe_handle_sof_rdi(struct ais_vfe_hw_core_info *core_info, struct ais_vfe_hw_work_data *work_data, enum ais_ife_output_path_id path) { struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[path]; uint64_t cur_sof_hw_ts = work_data->ts_hw[path].cur_sof_ts; uint64_t prev_sof_hw_ts = work_data->ts_hw[path].prev_sof_ts; p_rdi->frame_cnt++; if (p_rdi->num_buffer_hw_q) { struct ais_sof_info_t sof = {}; uint64_t ts_delta; uint8_t miss_sof = 0; if (cur_sof_hw_ts < prev_sof_hw_ts) ts_delta = cur_sof_hw_ts + (U64_MAX - prev_sof_hw_ts); else ts_delta = cur_sof_hw_ts - prev_sof_hw_ts; //check any missing SOFs if (p_rdi->frame_cnt > 1) { if (ts_delta == 0) { CAM_ERR(CAM_ISP, "IFE%d RDI%d ts_delta is 0", core_info->vfe_idx, path); } else { miss_sof = ais_vfe_get_num_missed_sof( cur_sof_hw_ts, prev_sof_hw_ts, p_rdi->last_sof_info.cur_sof_hw_ts, ts_delta); } } if (p_rdi->frame_cnt == 1 && prev_sof_hw_ts != 0) { //enq missed first frame sof.sof_ts = work_data->ts; sof.cur_sof_hw_ts = prev_sof_hw_ts; sof.frame_cnt = p_rdi->frame_cnt++; ais_vfe_q_sof(core_info, path, &sof); } else if (miss_sof > 0) { if (miss_sof > 1) { int i = 0; int miss_idx = miss_sof - 1; for (i = 0; i < (miss_sof - 1); i++) { sof.sof_ts = work_data->ts; sof.cur_sof_hw_ts = prev_sof_hw_ts - (ts_delta * miss_idx); sof.frame_cnt = p_rdi->frame_cnt++; ais_vfe_q_sof(core_info, path, &sof); miss_idx--; } } //enq prev sof.sof_ts = work_data->ts; sof.cur_sof_hw_ts = prev_sof_hw_ts; sof.frame_cnt = p_rdi->frame_cnt++; ais_vfe_q_sof(core_info, path, &sof); } //enq curr sof.sof_ts = work_data->ts; sof.cur_sof_hw_ts = prev_sof_hw_ts; sof.frame_cnt = p_rdi->frame_cnt; ais_vfe_q_sof(core_info, path, &sof); } else { CAM_DBG(CAM_ISP, "I%d R%d Flush SOF (%d) HW Q empty", core_info->vfe_idx, path, p_rdi->num_sof_info_q); if (p_rdi->num_sof_info_q) { struct ais_sof_info_t *p_sof_info; while (!list_empty(&p_rdi->sof_info_q)) { p_sof_info = list_first_entry( &p_rdi->sof_info_q, struct ais_sof_info_t, list); list_del_init(&p_sof_info->list); list_add_tail(&p_sof_info->list, &p_rdi->free_sof_info_list); } p_rdi->num_sof_info_q = 0; } //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; core_info->event.path = path; core_info->event.u.err_msg.reserved = 0; core_info->event_cb(core_info->event_cb_priv, &core_info->event); } p_rdi->last_sof_info.cur_sof_hw_ts = cur_sof_hw_ts; //send sof only for current frame core_info->event.type = AIS_IFE_MSG_SOF; core_info->event.path = path; core_info->event.u.sof_msg.frame_id = p_rdi->frame_cnt; core_info->event.u.sof_msg.hw_ts = cur_sof_hw_ts; core_info->event_cb(core_info->event_cb_priv, &core_info->event); } static int ais_vfe_handle_sof( static int ais_vfe_handle_sof( 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) Loading @@ -836,17 +1039,12 @@ static int ais_vfe_handle_sof( if (p_rdi->state != AIS_ISP_RESOURCE_STATE_STREAMING) if (p_rdi->state != AIS_ISP_RESOURCE_STATE_STREAMING) continue; continue; p_rdi->frame_cnt++; ais_vfe_handle_sof_rdi(core_info, work_data, path); p_rdi->sof_ts = work_data->ts; p_rdi->sof_hw_ts = work_data->ts_hw[path].cur_sof_ts; core_info->event.type = AIS_IFE_MSG_SOF; //enq buffers core_info->event.path = path; spin_lock_bh(&p_rdi->buffer_lock); core_info->event.u.sof_msg.frame_id = p_rdi->frame_cnt; ais_vfe_q_bufs_to_hw(core_info, path); core_info->event.u.sof_msg.hw_ts = p_rdi->sof_ts; spin_unlock_bh(&p_rdi->buffer_lock); core_info->event_cb(core_info->event_cb_priv, &core_info->event); } } return rc; return rc; Loading Loading @@ -914,19 +1112,32 @@ static void ais_vfe_bus_handle_client_frame_done( 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; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; struct ais_vfe_bus_ver2_hw_info *bus_hw_info = NULL; uint64_t frame_cnt; uint64_t sof_ts; uint64_t cur_sof_hw_ts; bool last_addr_match = false; bool last_addr_match = false; CAM_DBG(CAM_ISP, "Frame Done Client %d", path); CAM_DBG(CAM_ISP, "I%d|R%d last_addr 0x%x", core_info->vfe_idx, path, last_addr); if (last_addr == 0) { CAM_ERR(CAM_ISP, "I%d|R%d null last_addr", core_info->vfe_idx, path); return; } rdi_path = &core_info->rdi_out[path]; rdi_path = &core_info->rdi_out[path]; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; bus_hw_info = core_info->vfe_hw_info->bus_hw_info; spin_lock_bh(&rdi_path->buffer_lock); core_info->event.type = AIS_IFE_MSG_FRAME_DONE; core_info->event.path = path; while (rdi_path->num_buffer_hw_q && !last_addr_match) { while (rdi_path->num_buffer_hw_q && !last_addr_match) { struct ais_sof_info_t *p_sof_info = NULL; if (list_empty(&rdi_path->buffer_hw_q)) { if (list_empty(&rdi_path->buffer_hw_q)) { CAM_ERR(CAM_ISP, "Received RDI%d FD while SW Q empty", CAM_DBG(CAM_ISP, "I%d|R%d: FD while HW Q empty", path); core_info->vfe_idx, path); break; break; } } Loading @@ -935,17 +1146,39 @@ static void ais_vfe_bus_handle_client_frame_done( list_del_init(&vfe_buf->list); list_del_init(&vfe_buf->list); --rdi_path->num_buffer_hw_q; --rdi_path->num_buffer_hw_q; CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d DQ %d (0x%x) FIFO:%d|0x%x", CAM_DBG(CAM_ISP, "I%d|R%d BUF 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, last_addr); rdi_path->num_buffer_hw_q, last_addr); core_info->event.type = AIS_IFE_MSG_FRAME_DONE; if (!list_empty(&rdi_path->sof_info_q)) { core_info->event.path = path; p_sof_info = list_first_entry(&rdi_path->sof_info_q, core_info->event.u.frame_msg.frame_id = rdi_path->frame_cnt; struct ais_sof_info_t, list); list_del_init(&p_sof_info->list); rdi_path->num_sof_info_q--; } else CAM_ERR(CAM_ISP, "I%d|R%d: SOF info Q is empty", core_info->vfe_idx, path); if (p_sof_info) { frame_cnt = p_sof_info->frame_cnt; sof_ts = p_sof_info->sof_ts; cur_sof_hw_ts = p_sof_info->cur_sof_hw_ts; list_add_tail(&p_sof_info->list, &rdi_path->free_sof_info_list); } else { frame_cnt = sof_ts = cur_sof_hw_ts = 0; } CAM_DBG(CAM_ISP, "I%d|R%d|F%llu: si [%llu, %llu, %llu]", core_info->vfe_idx, path, frame_cnt, sof_ts, cur_sof_hw_ts); core_info->event.u.frame_msg.frame_id = frame_cnt; core_info->event.u.frame_msg.buf_idx = vfe_buf->bufIdx; core_info->event.u.frame_msg.buf_idx = vfe_buf->bufIdx; core_info->event.u.frame_msg.ts = rdi_path->sof_ts; core_info->event.u.frame_msg.ts = sof_ts; core_info->event.u.frame_msg.hw_ts = rdi_path->sof_hw_ts; core_info->event.u.frame_msg.hw_ts = cur_sof_hw_ts; core_info->event_cb(core_info->event_cb_priv, core_info->event_cb(core_info->event_cb_priv, &core_info->event); &core_info->event); Loading @@ -955,15 +1188,52 @@ static void ais_vfe_bus_handle_client_frame_done( else else CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr", CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr", core_info->vfe_idx, vfe_buf->bufIdx); 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, last_addr); core_info->vfe_idx, path, last_addr); ais_vfe_queue_to_hw(core_info, path); //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; core_info->event.path = path; core_info->event.u.err_msg.reserved = 1; core_info->event_cb(core_info->event_cb_priv, &core_info->event); } /* Flush SOF info Q if HW Buffer Q is empty */ if (rdi_path->num_buffer_hw_q == 0) { struct ais_sof_info_t *p_sof_info = NULL; CAM_DBG(CAM_ISP, "I%d|R%d|F%llu: Flush SOF (%d) HW Q empty", core_info->vfe_idx, path, frame_cnt, rdi_path->num_sof_info_q); while (!list_empty(&rdi_path->sof_info_q)) { p_sof_info = list_first_entry(&rdi_path->sof_info_q, struct ais_sof_info_t, list); list_del_init(&p_sof_info->list); list_add_tail(&p_sof_info->list, &rdi_path->free_sof_info_list); } rdi_path->num_sof_info_q = 0; //send warning core_info->event.type = AIS_IFE_MSG_OUTPUT_WARNING; core_info->event.path = path; core_info->event.u.err_msg.reserved = 0; core_info->event_cb(core_info->event_cb_priv, &core_info->event); } spin_lock_bh(&rdi_path->buffer_lock); ais_vfe_q_bufs_to_hw(core_info, path); spin_unlock_bh(&rdi_path->buffer_lock); spin_unlock_bh(&rdi_path->buffer_lock); } } Loading
drivers/media/platform/msm/ais/ais_isp/vfe_hw/ais_vfe_core.h +16 −3 Original line number Original line Diff line number Diff line Loading @@ -20,8 +20,9 @@ #include "ais_vfe_bus_ver2.h" #include "ais_vfe_bus_ver2.h" #include "ais_vfe_top_ver2.h" #include "ais_vfe_top_ver2.h" #define AIS_VFE_WORKQ_NUM_TASK 16 #define AIS_VFE_WORKQ_NUM_TASK 20 #define AIS_VFE_MAX_BUF 12 #define AIS_VFE_MAX_BUF 12 #define AIS_VFE_MAX_SOF_INFO 8 enum ais_vfe_hw_irq_event { enum ais_vfe_hw_irq_event { AIS_VFE_HW_IRQ_EVENT_SOF, AIS_VFE_HW_IRQ_EVENT_SOF, Loading Loading @@ -83,6 +84,14 @@ struct ais_vfe_buffer_t { uint32_t bufIdx; uint32_t bufIdx; }; }; struct ais_sof_info_t { struct list_head list; uint64_t frame_cnt; uint64_t sof_ts; uint64_t cur_sof_hw_ts; uint64_t prev_sof_hw_ts; }; struct ais_vfe_rdi_output { struct ais_vfe_rdi_output { enum ais_isp_resource_state state; enum ais_isp_resource_state state; Loading @@ -96,8 +105,12 @@ struct ais_vfe_rdi_output { struct list_head free_buffer_list; struct list_head free_buffer_list; uint64_t frame_cnt; uint64_t frame_cnt; uint64_t sof_ts; uint64_t sof_hw_ts; uint8_t num_sof_info_q; struct ais_sof_info_t sof_info[AIS_VFE_MAX_SOF_INFO]; struct list_head sof_info_q; struct list_head free_sof_info_list; struct ais_sof_info_t last_sof_info; }; }; struct ais_vfe_hw_core_info { struct ais_vfe_hw_core_info { Loading
drivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe17x/ais_vfe170.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -429,6 +429,7 @@ static struct ais_vfe_bus_ver2_hw_info vfe170_bus_hw_info = { .addr_sync_cfg = 0x0000207C, .addr_sync_cfg = 0x0000207C, .addr_sync_frame_hdr = 0x00002080, .addr_sync_frame_hdr = 0x00002080, .addr_sync_no_sync = 0x00002084, .addr_sync_no_sync = 0x00002084, .addr_fifo_status = 0x000020A8, .debug_status_cfg = 0x0000226C, .debug_status_cfg = 0x0000226C, .debug_status_0 = 0x00002270, .debug_status_0 = 0x00002270, }, }, Loading