Loading drivers/cam_cdm/cam_cdm.h +2 −1 Original line number Diff line number Diff line Loading @@ -440,6 +440,7 @@ struct cam_cdm_work_payload { uint32_t irq_status; uint32_t irq_data; int fifo_idx; ktime_t workq_scheduled_ts; struct work_struct work; }; Loading Loading @@ -476,7 +477,7 @@ struct cam_cdm_bl_fifo { uint8_t bl_tag; uint32_t bl_depth; uint8_t last_bl_tag_done; uint32_t work_record; atomic_t work_record; }; /** Loading drivers/cam_cdm/cam_cdm_core_common.c +1 −4 Original line number Diff line number Diff line Loading @@ -206,6 +206,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw, } else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE || status == CAM_CDM_CB_STATUS_HW_FLUSH || status == CAM_CDM_CB_STATUS_HW_RESUBMIT || status == CAM_CDM_CB_STATUS_INVALID_BL_CMD || status == CAM_CDM_CB_STATUS_HW_ERROR) { int client_idx; struct cam_cdm_bl_cb_request_entry *node = Loading Loading @@ -800,13 +801,11 @@ int cam_cdm_process_cmd(void *hw_priv, } idx = CAM_CDM_GET_CLIENT_IDX(*handle); mutex_lock(&cdm_hw->hw_mutex); client = core->clients[idx]; if (!client) { CAM_ERR(CAM_CDM, "Client not present for handle %d", *handle); mutex_unlock(&cdm_hw->hw_mutex); break; } Loading @@ -814,12 +813,10 @@ int cam_cdm_process_cmd(void *hw_priv, CAM_ERR(CAM_CDM, "handle mismatch, client handle %d index %d received handle %d", client->handle, idx, *handle); mutex_unlock(&cdm_hw->hw_mutex); break; } rc = cam_hw_cdm_hang_detect(cdm_hw, *handle); mutex_unlock(&cdm_hw->hw_mutex); break; } case CAM_CDM_HW_INTF_DUMP_DBG_REGS: Loading drivers/cam_cdm/cam_cdm_hw_core.c +205 −117 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "cam_cdm_hw_reg_2_1.h" #include "camera_main.h" #include "cam_trace.h" #include "cam_req_mgr_workq.h" #define CAM_CDM_BL_FIFO_WAIT_TIMEOUT 2000 #define CAM_CDM_DBG_GEN_IRQ_USR_DATA 0xff Loading Loading @@ -569,7 +570,7 @@ int cam_hw_cdm_wait_for_bl_fifo( CAM_DBG(CAM_CDM, "BL slot available_cnt=%d requested=%d", (available_bl_slots - 1), bl_count); rc = bl_count; rc = available_bl_slots - 1; break; } else if (0 == (available_bl_slots - 1)) { rc = cam_hw_cdm_enable_bl_done_irq(cdm_hw, Loading @@ -595,7 +596,7 @@ int cam_hw_cdm_wait_for_bl_fifo( if (cam_hw_cdm_enable_bl_done_irq(cdm_hw, false, fifo_idx)) CAM_ERR(CAM_CDM, "Disable BL done irq failed"); rc = 0; rc = 1; CAM_DBG(CAM_CDM, "CDM HW is ready for data"); } else { rc = (bl_count - (available_bl_slots - 1)); Loading Loading @@ -702,6 +703,7 @@ int cam_hw_cdm_submit_gen_irq( core->bl_fifo[fifo_idx].bl_tag); list_del_init(&node->entry); kfree(node); node = NULL; rc = -EIO; goto end; } Loading @@ -712,6 +714,7 @@ int cam_hw_cdm_submit_gen_irq( core->bl_fifo[fifo_idx].bl_tag); list_del_init(&node->entry); kfree(node); node = NULL; rc = -EIO; } Loading Loading @@ -922,8 +925,6 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw, rc = -EIO; break; } } else { write_count--; } if (req->data->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE) { Loading Loading @@ -1026,27 +1027,58 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw, rc = -EIO; break; } write_count--; CAM_DBG(CAM_CDM, "commit success BL %d tag=%d", i, core->bl_fifo[fifo_idx].bl_tag); } core->bl_fifo[fifo_idx].bl_tag++; if (cdm_cmd->cmd[i].enable_debug_gen_irq) { if (write_count == 0) { write_count = cam_hw_cdm_wait_for_bl_fifo( cdm_hw, 1, fifo_idx); if (write_count < 0) { CAM_ERR(CAM_CDM, "wait for bl fifo failed %d:%d", i, req->data->cmd_arrary_count); rc = -EIO; break; } } rc = cam_hw_cdm_submit_debug_gen_irq(cdm_hw, fifo_idx); if (rc == 0) if (rc == 0) { write_count--; core->bl_fifo[fifo_idx].bl_tag++; } if (core->bl_fifo[fifo_idx].bl_tag >= (bl_fifo->bl_depth - 1)) core->bl_fifo[fifo_idx].bl_tag = 0; } if ((req->data->flag == true) && if ((!rc) && (req->data->flag == true) && (i == (req->data->cmd_arrary_count - 1))) { if (write_count == 0) { write_count = cam_hw_cdm_wait_for_bl_fifo( cdm_hw, 1, fifo_idx); if (write_count < 0) { CAM_ERR(CAM_CDM, "wait for bl fifo failed %d:%d", i, req->data->cmd_arrary_count); rc = -EIO; break; } } if (core->arbitration != CAM_CDM_ARBITRATION_PRIORITY_BASED) { rc = cam_hw_cdm_submit_gen_irq( cdm_hw, req, fifo_idx, cdm_cmd->gen_irq_arb); Loading Loading @@ -1080,7 +1112,8 @@ static void cam_hw_cdm_reset_cleanup( struct cam_cdm_bl_cb_request_entry *node, *tnode; bool flush_hw = false; if (test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status)) if (test_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status) || test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status)) flush_hw = true; for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) { Loading @@ -1104,10 +1137,11 @@ static void cam_hw_cdm_reset_cleanup( } list_del_init(&node->entry); kfree(node); node = NULL; } core->bl_fifo[i].bl_tag = 0; core->bl_fifo[i].last_bl_tag_done = -1; core->bl_fifo[i].work_record = 0; atomic_set(&core->bl_fifo[i].work_record, 0); } } Loading @@ -1116,24 +1150,33 @@ static void cam_hw_cdm_work(struct work_struct *work) struct cam_cdm_work_payload *payload; struct cam_hw_info *cdm_hw; struct cam_cdm *core; int i; int i, fifo_idx; struct cam_cdm_bl_cb_request_entry *tnode = NULL; struct cam_cdm_bl_cb_request_entry *node = NULL; payload = container_of(work, struct cam_cdm_work_payload, work); if (payload) { if (!payload) { CAM_ERR(CAM_CDM, "NULL payload"); return; } cdm_hw = payload->hw; core = (struct cam_cdm *)cdm_hw->core_info; if (payload->fifo_idx >= core->offsets->reg_data->num_bl_fifo) { fifo_idx = payload->fifo_idx; if (fifo_idx >= core->offsets->reg_data->num_bl_fifo) { CAM_ERR(CAM_CDM, "Invalid fifo idx %d", payload->fifo_idx); fifo_idx); kfree(payload); payload = NULL; return; } cam_req_mgr_thread_switch_delay_detect( payload->workq_scheduled_ts); CAM_DBG(CAM_CDM, "IRQ status=0x%x", payload->irq_status); if (payload->irq_status & CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK) { struct cam_cdm_bl_cb_request_entry *node, *tnode; CAM_DBG(CAM_CDM, "inline IRQ data=0x%x last tag: 0x%x", payload->irq_data, core->bl_fifo[payload->fifo_idx] Loading @@ -1142,35 +1185,32 @@ static void cam_hw_cdm_work(struct work_struct *work) if (payload->irq_data == 0xff) { CAM_INFO(CAM_CDM, "Debug genirq received"); kfree(payload); payload = NULL; return; } mutex_lock(&core->bl_fifo[payload->fifo_idx] .fifo_lock); mutex_lock(&core->bl_fifo[fifo_idx].fifo_lock); if (core->bl_fifo[payload->fifo_idx].work_record) core->bl_fifo[payload->fifo_idx].work_record--; if (atomic_read(&core->bl_fifo[fifo_idx].work_record)) atomic_dec(&core->bl_fifo[fifo_idx].work_record); if (list_empty(&core->bl_fifo[payload->fifo_idx] if (list_empty(&core->bl_fifo[fifo_idx] .bl_request_list)) { CAM_INFO(CAM_CDM, "Fifo list empty, idx %d tag %d arb %d", payload->fifo_idx, payload->irq_data, fifo_idx, payload->irq_data, core->arbitration); mutex_unlock(&core->bl_fifo[payload->fifo_idx] mutex_unlock(&core->bl_fifo[fifo_idx] .fifo_lock); return; } if (core->bl_fifo[payload->fifo_idx] .last_bl_tag_done != if (core->bl_fifo[fifo_idx].last_bl_tag_done != payload->irq_data) { core->bl_fifo[payload->fifo_idx] .last_bl_tag_done = core->bl_fifo[fifo_idx].last_bl_tag_done = payload->irq_data; list_for_each_entry_safe(node, tnode, &core->bl_fifo[payload->fifo_idx] .bl_request_list, &core->bl_fifo[fifo_idx].bl_request_list, entry) { if (node->request_type == CAM_HW_CDM_BL_CB_CLIENT) { Loading @@ -1187,8 +1227,11 @@ static void cam_hw_cdm_work(struct work_struct *work) list_del_init(&node->entry); if (node->bl_tag == payload->irq_data) { kfree(node); node = NULL; break; } kfree(node); node = NULL; } } else { CAM_INFO(CAM_CDM, Loading @@ -1209,6 +1252,8 @@ static void cam_hw_cdm_work(struct work_struct *work) } if (payload->irq_status & CAM_CDM_IRQ_STATUS_ERRORS) { int reset_hw_hdl = 0x0; CAM_ERR_RATE_LIMIT(CAM_CDM, "CDM Error IRQ status %d\n", payload->irq_status); Loading @@ -1217,10 +1262,45 @@ static void cam_hw_cdm_work(struct work_struct *work) for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) mutex_lock(&core->bl_fifo[i].fifo_lock); /* * First pause CDM, If it fails still proceed * to dump debug info */ cam_hw_cdm_pause_core(cdm_hw, true); cam_hw_cdm_dump_core_debug_registers(cdm_hw, true); if (payload->irq_status & CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK) { node = list_first_entry_or_null( &core->bl_fifo[payload->fifo_idx].bl_request_list, struct cam_cdm_bl_cb_request_entry, entry); if (node != NULL) { if (node->request_type == CAM_HW_CDM_BL_CB_CLIENT) { cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_INVALID_BL_CMD, (void *)node); } else if (node->request_type == CAM_HW_CDM_BL_CB_INTERNAL) { CAM_ERR(CAM_CDM, "Invalid node=%pK %d", node, node->request_type); } list_del_init(&node->entry); kfree(node); } } /* Resume CDM back */ cam_hw_cdm_pause_core(cdm_hw, false); for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) mutex_unlock(&core->bl_fifo[i].fifo_lock); if (payload->irq_status & CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK) cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl); mutex_unlock(&cdm_hw->hw_mutex); if (!(payload->irq_status & CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK)) Loading @@ -1228,9 +1308,7 @@ static void cam_hw_cdm_work(struct work_struct *work) &core->cdm_status); } kfree(payload); } else { CAM_ERR(CAM_CDM, "NULL payload"); } payload = NULL; } Loading Loading @@ -1369,7 +1447,9 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) return IRQ_HANDLED; } cdm_core->bl_fifo[i].work_record++; atomic_inc(&cdm_core->bl_fifo[i].work_record); payload[i]->workq_scheduled_ts = ktime_get(); work_status = queue_work( cdm_core->bl_fifo[i].work_queue, &payload[i]->work); Loading @@ -1379,6 +1459,7 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) "Failed to queue work for FIFO: %d irq=0x%x", i, payload[i]->irq_status); kfree(payload[i]); payload[i] = NULL; } } if (rst_done_cnt == cdm_core->offsets->reg_data->num_bl_fifo_irq) { Loading Loading @@ -1629,6 +1710,7 @@ int cam_hw_cdm_handle_error_info( } list_del_init(&node->entry); kfree(node); node = NULL; } cam_hw_cdm_reset_cleanup(cdm_hw, reset_hw_hdl); Loading Loading @@ -1679,20 +1761,14 @@ int cam_hw_cdm_hang_detect( cdm_core = (struct cam_cdm *)cdm_hw->core_info; for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) mutex_lock(&cdm_core->bl_fifo[i].fifo_lock); for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) if (cdm_core->bl_fifo[i].work_record) { if (atomic_read(&cdm_core->bl_fifo[i].work_record)) { CAM_WARN(CAM_CDM, "workqueue got delayed, bl_fifo: %d, work_record :%u", i, cdm_core->bl_fifo[i].work_record); "workqueue got delayed, work_record :%u", atomic_read(&cdm_core->bl_fifo[i].work_record)); rc = 0; break; } for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) mutex_unlock(&cdm_core->bl_fifo[i].fifo_lock); return rc; } Loading Loading @@ -1797,7 +1873,7 @@ int cam_hw_cdm_init(void *hw_priv, } for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) { cdm_core->bl_fifo[i].last_bl_tag_done = -1; cdm_core->bl_fifo[i].work_record = 0; atomic_set(&cdm_core->bl_fifo[i].work_record, 0); } rc = cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl); Loading Loading @@ -1856,6 +1932,7 @@ int cam_hw_cdm_deinit(void *hw_priv, &cdm_core->bl_fifo[i].bl_request_list, entry) { list_del_init(&node->entry); kfree(node); node = NULL; } } Loading Loading @@ -1931,13 +2008,16 @@ static int cam_hw_cdm_component_bind(struct device *dev, cdm_hw = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); if (!cdm_hw) { kfree(cdm_hw_intf); cdm_hw_intf = NULL; return -ENOMEM; } cdm_hw->core_info = kzalloc(sizeof(struct cam_cdm), GFP_KERNEL); if (!cdm_hw->core_info) { kfree(cdm_hw); cdm_hw = NULL; kfree(cdm_hw_intf); cdm_hw_intf = NULL; return -ENOMEM; } Loading Loading @@ -2174,11 +2254,15 @@ static int cam_hw_cdm_component_bind(struct device *dev, mutex_unlock(&cdm_hw->hw_mutex); release_private_mem: kfree(cdm_hw->soc_info.soc_private); cdm_hw->soc_info.soc_private = NULL; release_mem: mutex_destroy(&cdm_hw->hw_mutex); kfree(cdm_hw_intf); cdm_hw_intf = NULL; kfree(cdm_hw->core_info); cdm_hw->core_info = NULL; kfree(cdm_hw); cdm_hw = NULL; return rc; } Loading Loading @@ -2256,9 +2340,13 @@ static void cam_hw_cdm_component_unbind(struct device *dev, mutex_destroy(&cdm_hw->hw_mutex); kfree(cdm_hw->soc_info.soc_private); cdm_hw->soc_info.soc_private = NULL; kfree(cdm_hw_intf); cdm_hw_intf = NULL; kfree(cdm_hw->core_info); cdm_hw->core_info = NULL; kfree(cdm_hw); cdm_hw = NULL; } const static struct component_ops cam_hw_cdm_component_ops = { Loading drivers/cam_cdm/cam_cdm_intf_api.h +37 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ #include "cam_cdm_util.h" #include "cam_soc_util.h" #define CAM_CDM_BL_CMD_MAX 25 /* enum cam_cdm_id - Enum for possible CAM CDM hardwares */ enum cam_cdm_id { CAM_CDM_VIRTUAL, Loading Loading @@ -151,6 +153,41 @@ struct cam_cdm_bl_request { struct cam_cdm_bl_cmd cmd[1]; }; /** * struct cam_cdm_bl_data - last submiited CDM BL data * * @mem_handle : Input mem handle of bl cmd * @hw_addr : Hw address of submitted Bl command * @offset : Input offset of the actual bl cmd in the memory pointed * by mem_handle * @len : length of submitted Bl command to CDM. * @input_len : Input length of the BL command, Cannot be more than 1MB and * this is will be validated with offset+size of the memory pointed * by mem_handle * @type : CDM bl cmd addr types. */ struct cam_cdm_bl_data { int32_t mem_handle; dma_addr_t hw_addr; uint32_t offset; size_t len; uint32_t input_len; enum cam_cdm_bl_cmd_addr_type type; }; /** * struct cam_cdm_bl_info * * @bl_count : No. of Bl commands submiited to CDM. * @cmd : payload holding the BL cmd's arrary * that is sumbitted. * */ struct cam_cdm_bl_info { int32_t bl_count; struct cam_cdm_bl_data cmd[CAM_CDM_BL_CMD_MAX]; }; /** * @brief : API to get the CDM capabilities for a camera device type * Loading drivers/cam_cdm/cam_cdm_util.c +66 −12 Original line number Diff line number Diff line Loading @@ -689,25 +689,53 @@ int cam_cdm_util_cmd_buf_write(void __iomem **current_device_base, return ret; } static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { long ret = 0; struct cdm_dmi_cmd *p_dmi_cmd; uint32_t *temp_ptr = cmd_buf_addr; p_dmi_cmd = (struct cdm_dmi_cmd *)cmd_buf_addr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI]; CAM_INFO(CAM_CDM, "DMI"); if (temp_ptr > cmd_buf_addr_end) CAM_ERR(CAM_CDM, "Invalid cmd start addr:%pK end addr:%pK", temp_ptr, cmd_buf_addr_end); CAM_INFO(CAM_CDM, "DMI: LEN: %u DMIAddr: 0x%X DMISel: 0x%X LUT_addr: 0x%X", p_dmi_cmd->length, p_dmi_cmd->DMIAddr, p_dmi_cmd->DMISel, p_dmi_cmd->addr); return ret; } static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { long ret = 0; struct cdm_indirect_cmd *p_indirect_cmd; uint32_t *temp_ptr = cmd_buf_addr; p_indirect_cmd = (struct cdm_indirect_cmd *)cmd_buf_addr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT]; CAM_INFO(CAM_CDM, "Buff Indirect"); if (temp_ptr > cmd_buf_addr_end) CAM_ERR(CAM_CDM, "Invalid cmd start addr:%pK end addr:%pK", temp_ptr, cmd_buf_addr_end); CAM_INFO(CAM_CDM, "Buff Indirect: LEN: %u addr: 0x%X", p_indirect_cmd->length, p_indirect_cmd->addr); return ret; } static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { long ret = 0; struct cdm_regcontinuous_cmd *p_regcont_cmd; Loading @@ -722,6 +750,12 @@ static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr) p_regcont_cmd->count, p_regcont_cmd->offset); for (i = 0; i < p_regcont_cmd->count; i++) { if (temp_ptr > cmd_buf_addr_end) { CAM_ERR(CAM_CDM, "Invalid cmd(%d) start addr:%pK end addr:%pK", i, temp_ptr, cmd_buf_addr_end); break; } CAM_INFO(CAM_CDM, "DATA_%d: 0x%X", i, *temp_ptr); temp_ptr++; Loading @@ -731,7 +765,8 @@ static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr) return ret; } static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { struct cdm_regrandom_cmd *p_regrand_cmd; uint32_t *temp_ptr = cmd_buf_addr; Loading @@ -746,6 +781,12 @@ static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr) p_regrand_cmd->count); for (i = 0; i < p_regrand_cmd->count; i++) { if (temp_ptr > cmd_buf_addr_end) { CAM_ERR(CAM_CDM, "Invalid cmd(%d) start addr:%pK end addr:%pK", i, temp_ptr, cmd_buf_addr_end); break; } CAM_INFO(CAM_CDM, "OFFSET_%d: 0x%X DATA_%d: 0x%X", i, *temp_ptr & CAM_CDM_REG_OFFSET_MASK, i, *(temp_ptr + 1)); Loading Loading @@ -778,15 +819,22 @@ static long cam_cdm_util_dump_wait_event_cmd(uint32_t *cmd_buf_addr) return ret; } static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { long ret = 0; struct cdm_changebase_cmd *p_cbase_cmd; uint32_t *temp_ptr = cmd_buf_addr; p_cbase_cmd = (struct cdm_changebase_cmd *)temp_ptr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE]; if (temp_ptr > cmd_buf_addr_end) CAM_ERR(CAM_CDM, "Invalid cmd start addr:%pK end addr:%pK", temp_ptr, cmd_buf_addr_end); CAM_INFO(CAM_CDM, "CHANGE_BASE: 0x%X", p_cbase_cmd->base); Loading Loading @@ -819,6 +867,7 @@ void cam_cdm_util_dump_cmd_buf( uint32_t *cmd_buf_start, uint32_t *cmd_buf_end) { uint32_t *buf_now = cmd_buf_start; uint32_t *buf_end = cmd_buf_end; uint32_t cmd = 0; if (!cmd_buf_start || !cmd_buf_end) { Loading @@ -834,16 +883,20 @@ void cam_cdm_util_dump_cmd_buf( case CAM_CDM_CMD_DMI: case CAM_CDM_CMD_DMI_32: case CAM_CDM_CMD_DMI_64: buf_now += cam_cdm_util_dump_dmi_cmd(buf_now); buf_now += cam_cdm_util_dump_dmi_cmd(buf_now, buf_end); break; case CAM_CDM_CMD_REG_CONT: buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now); buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now, buf_end); break; case CAM_CDM_CMD_REG_RANDOM: buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now); buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now, buf_end); break; case CAM_CDM_CMD_BUFF_INDIRECT: buf_now += cam_cdm_util_dump_buff_indirect(buf_now); buf_now += cam_cdm_util_dump_buff_indirect(buf_now, buf_end); break; case CAM_CDM_CMD_GEN_IRQ: buf_now += cam_cdm_util_dump_gen_irq_cmd(buf_now); Loading @@ -852,7 +905,8 @@ void cam_cdm_util_dump_cmd_buf( buf_now += cam_cdm_util_dump_wait_event_cmd(buf_now); break; case CAM_CDM_CMD_CHANGE_BASE: buf_now += cam_cdm_util_dump_change_base_cmd(buf_now); buf_now += cam_cdm_util_dump_change_base_cmd(buf_now, buf_end); break; case CAM_CDM_CMD_PERF_CTRL: buf_now += cam_cdm_util_dump_perf_ctrl_cmd(buf_now); Loading Loading
drivers/cam_cdm/cam_cdm.h +2 −1 Original line number Diff line number Diff line Loading @@ -440,6 +440,7 @@ struct cam_cdm_work_payload { uint32_t irq_status; uint32_t irq_data; int fifo_idx; ktime_t workq_scheduled_ts; struct work_struct work; }; Loading Loading @@ -476,7 +477,7 @@ struct cam_cdm_bl_fifo { uint8_t bl_tag; uint32_t bl_depth; uint8_t last_bl_tag_done; uint32_t work_record; atomic_t work_record; }; /** Loading
drivers/cam_cdm/cam_cdm_core_common.c +1 −4 Original line number Diff line number Diff line Loading @@ -206,6 +206,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw, } else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE || status == CAM_CDM_CB_STATUS_HW_FLUSH || status == CAM_CDM_CB_STATUS_HW_RESUBMIT || status == CAM_CDM_CB_STATUS_INVALID_BL_CMD || status == CAM_CDM_CB_STATUS_HW_ERROR) { int client_idx; struct cam_cdm_bl_cb_request_entry *node = Loading Loading @@ -800,13 +801,11 @@ int cam_cdm_process_cmd(void *hw_priv, } idx = CAM_CDM_GET_CLIENT_IDX(*handle); mutex_lock(&cdm_hw->hw_mutex); client = core->clients[idx]; if (!client) { CAM_ERR(CAM_CDM, "Client not present for handle %d", *handle); mutex_unlock(&cdm_hw->hw_mutex); break; } Loading @@ -814,12 +813,10 @@ int cam_cdm_process_cmd(void *hw_priv, CAM_ERR(CAM_CDM, "handle mismatch, client handle %d index %d received handle %d", client->handle, idx, *handle); mutex_unlock(&cdm_hw->hw_mutex); break; } rc = cam_hw_cdm_hang_detect(cdm_hw, *handle); mutex_unlock(&cdm_hw->hw_mutex); break; } case CAM_CDM_HW_INTF_DUMP_DBG_REGS: Loading
drivers/cam_cdm/cam_cdm_hw_core.c +205 −117 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "cam_cdm_hw_reg_2_1.h" #include "camera_main.h" #include "cam_trace.h" #include "cam_req_mgr_workq.h" #define CAM_CDM_BL_FIFO_WAIT_TIMEOUT 2000 #define CAM_CDM_DBG_GEN_IRQ_USR_DATA 0xff Loading Loading @@ -569,7 +570,7 @@ int cam_hw_cdm_wait_for_bl_fifo( CAM_DBG(CAM_CDM, "BL slot available_cnt=%d requested=%d", (available_bl_slots - 1), bl_count); rc = bl_count; rc = available_bl_slots - 1; break; } else if (0 == (available_bl_slots - 1)) { rc = cam_hw_cdm_enable_bl_done_irq(cdm_hw, Loading @@ -595,7 +596,7 @@ int cam_hw_cdm_wait_for_bl_fifo( if (cam_hw_cdm_enable_bl_done_irq(cdm_hw, false, fifo_idx)) CAM_ERR(CAM_CDM, "Disable BL done irq failed"); rc = 0; rc = 1; CAM_DBG(CAM_CDM, "CDM HW is ready for data"); } else { rc = (bl_count - (available_bl_slots - 1)); Loading Loading @@ -702,6 +703,7 @@ int cam_hw_cdm_submit_gen_irq( core->bl_fifo[fifo_idx].bl_tag); list_del_init(&node->entry); kfree(node); node = NULL; rc = -EIO; goto end; } Loading @@ -712,6 +714,7 @@ int cam_hw_cdm_submit_gen_irq( core->bl_fifo[fifo_idx].bl_tag); list_del_init(&node->entry); kfree(node); node = NULL; rc = -EIO; } Loading Loading @@ -922,8 +925,6 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw, rc = -EIO; break; } } else { write_count--; } if (req->data->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE) { Loading Loading @@ -1026,27 +1027,58 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw, rc = -EIO; break; } write_count--; CAM_DBG(CAM_CDM, "commit success BL %d tag=%d", i, core->bl_fifo[fifo_idx].bl_tag); } core->bl_fifo[fifo_idx].bl_tag++; if (cdm_cmd->cmd[i].enable_debug_gen_irq) { if (write_count == 0) { write_count = cam_hw_cdm_wait_for_bl_fifo( cdm_hw, 1, fifo_idx); if (write_count < 0) { CAM_ERR(CAM_CDM, "wait for bl fifo failed %d:%d", i, req->data->cmd_arrary_count); rc = -EIO; break; } } rc = cam_hw_cdm_submit_debug_gen_irq(cdm_hw, fifo_idx); if (rc == 0) if (rc == 0) { write_count--; core->bl_fifo[fifo_idx].bl_tag++; } if (core->bl_fifo[fifo_idx].bl_tag >= (bl_fifo->bl_depth - 1)) core->bl_fifo[fifo_idx].bl_tag = 0; } if ((req->data->flag == true) && if ((!rc) && (req->data->flag == true) && (i == (req->data->cmd_arrary_count - 1))) { if (write_count == 0) { write_count = cam_hw_cdm_wait_for_bl_fifo( cdm_hw, 1, fifo_idx); if (write_count < 0) { CAM_ERR(CAM_CDM, "wait for bl fifo failed %d:%d", i, req->data->cmd_arrary_count); rc = -EIO; break; } } if (core->arbitration != CAM_CDM_ARBITRATION_PRIORITY_BASED) { rc = cam_hw_cdm_submit_gen_irq( cdm_hw, req, fifo_idx, cdm_cmd->gen_irq_arb); Loading Loading @@ -1080,7 +1112,8 @@ static void cam_hw_cdm_reset_cleanup( struct cam_cdm_bl_cb_request_entry *node, *tnode; bool flush_hw = false; if (test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status)) if (test_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status) || test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status)) flush_hw = true; for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) { Loading @@ -1104,10 +1137,11 @@ static void cam_hw_cdm_reset_cleanup( } list_del_init(&node->entry); kfree(node); node = NULL; } core->bl_fifo[i].bl_tag = 0; core->bl_fifo[i].last_bl_tag_done = -1; core->bl_fifo[i].work_record = 0; atomic_set(&core->bl_fifo[i].work_record, 0); } } Loading @@ -1116,24 +1150,33 @@ static void cam_hw_cdm_work(struct work_struct *work) struct cam_cdm_work_payload *payload; struct cam_hw_info *cdm_hw; struct cam_cdm *core; int i; int i, fifo_idx; struct cam_cdm_bl_cb_request_entry *tnode = NULL; struct cam_cdm_bl_cb_request_entry *node = NULL; payload = container_of(work, struct cam_cdm_work_payload, work); if (payload) { if (!payload) { CAM_ERR(CAM_CDM, "NULL payload"); return; } cdm_hw = payload->hw; core = (struct cam_cdm *)cdm_hw->core_info; if (payload->fifo_idx >= core->offsets->reg_data->num_bl_fifo) { fifo_idx = payload->fifo_idx; if (fifo_idx >= core->offsets->reg_data->num_bl_fifo) { CAM_ERR(CAM_CDM, "Invalid fifo idx %d", payload->fifo_idx); fifo_idx); kfree(payload); payload = NULL; return; } cam_req_mgr_thread_switch_delay_detect( payload->workq_scheduled_ts); CAM_DBG(CAM_CDM, "IRQ status=0x%x", payload->irq_status); if (payload->irq_status & CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK) { struct cam_cdm_bl_cb_request_entry *node, *tnode; CAM_DBG(CAM_CDM, "inline IRQ data=0x%x last tag: 0x%x", payload->irq_data, core->bl_fifo[payload->fifo_idx] Loading @@ -1142,35 +1185,32 @@ static void cam_hw_cdm_work(struct work_struct *work) if (payload->irq_data == 0xff) { CAM_INFO(CAM_CDM, "Debug genirq received"); kfree(payload); payload = NULL; return; } mutex_lock(&core->bl_fifo[payload->fifo_idx] .fifo_lock); mutex_lock(&core->bl_fifo[fifo_idx].fifo_lock); if (core->bl_fifo[payload->fifo_idx].work_record) core->bl_fifo[payload->fifo_idx].work_record--; if (atomic_read(&core->bl_fifo[fifo_idx].work_record)) atomic_dec(&core->bl_fifo[fifo_idx].work_record); if (list_empty(&core->bl_fifo[payload->fifo_idx] if (list_empty(&core->bl_fifo[fifo_idx] .bl_request_list)) { CAM_INFO(CAM_CDM, "Fifo list empty, idx %d tag %d arb %d", payload->fifo_idx, payload->irq_data, fifo_idx, payload->irq_data, core->arbitration); mutex_unlock(&core->bl_fifo[payload->fifo_idx] mutex_unlock(&core->bl_fifo[fifo_idx] .fifo_lock); return; } if (core->bl_fifo[payload->fifo_idx] .last_bl_tag_done != if (core->bl_fifo[fifo_idx].last_bl_tag_done != payload->irq_data) { core->bl_fifo[payload->fifo_idx] .last_bl_tag_done = core->bl_fifo[fifo_idx].last_bl_tag_done = payload->irq_data; list_for_each_entry_safe(node, tnode, &core->bl_fifo[payload->fifo_idx] .bl_request_list, &core->bl_fifo[fifo_idx].bl_request_list, entry) { if (node->request_type == CAM_HW_CDM_BL_CB_CLIENT) { Loading @@ -1187,8 +1227,11 @@ static void cam_hw_cdm_work(struct work_struct *work) list_del_init(&node->entry); if (node->bl_tag == payload->irq_data) { kfree(node); node = NULL; break; } kfree(node); node = NULL; } } else { CAM_INFO(CAM_CDM, Loading @@ -1209,6 +1252,8 @@ static void cam_hw_cdm_work(struct work_struct *work) } if (payload->irq_status & CAM_CDM_IRQ_STATUS_ERRORS) { int reset_hw_hdl = 0x0; CAM_ERR_RATE_LIMIT(CAM_CDM, "CDM Error IRQ status %d\n", payload->irq_status); Loading @@ -1217,10 +1262,45 @@ static void cam_hw_cdm_work(struct work_struct *work) for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) mutex_lock(&core->bl_fifo[i].fifo_lock); /* * First pause CDM, If it fails still proceed * to dump debug info */ cam_hw_cdm_pause_core(cdm_hw, true); cam_hw_cdm_dump_core_debug_registers(cdm_hw, true); if (payload->irq_status & CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK) { node = list_first_entry_or_null( &core->bl_fifo[payload->fifo_idx].bl_request_list, struct cam_cdm_bl_cb_request_entry, entry); if (node != NULL) { if (node->request_type == CAM_HW_CDM_BL_CB_CLIENT) { cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_INVALID_BL_CMD, (void *)node); } else if (node->request_type == CAM_HW_CDM_BL_CB_INTERNAL) { CAM_ERR(CAM_CDM, "Invalid node=%pK %d", node, node->request_type); } list_del_init(&node->entry); kfree(node); } } /* Resume CDM back */ cam_hw_cdm_pause_core(cdm_hw, false); for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) mutex_unlock(&core->bl_fifo[i].fifo_lock); if (payload->irq_status & CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK) cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl); mutex_unlock(&cdm_hw->hw_mutex); if (!(payload->irq_status & CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK)) Loading @@ -1228,9 +1308,7 @@ static void cam_hw_cdm_work(struct work_struct *work) &core->cdm_status); } kfree(payload); } else { CAM_ERR(CAM_CDM, "NULL payload"); } payload = NULL; } Loading Loading @@ -1369,7 +1447,9 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) return IRQ_HANDLED; } cdm_core->bl_fifo[i].work_record++; atomic_inc(&cdm_core->bl_fifo[i].work_record); payload[i]->workq_scheduled_ts = ktime_get(); work_status = queue_work( cdm_core->bl_fifo[i].work_queue, &payload[i]->work); Loading @@ -1379,6 +1459,7 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) "Failed to queue work for FIFO: %d irq=0x%x", i, payload[i]->irq_status); kfree(payload[i]); payload[i] = NULL; } } if (rst_done_cnt == cdm_core->offsets->reg_data->num_bl_fifo_irq) { Loading Loading @@ -1629,6 +1710,7 @@ int cam_hw_cdm_handle_error_info( } list_del_init(&node->entry); kfree(node); node = NULL; } cam_hw_cdm_reset_cleanup(cdm_hw, reset_hw_hdl); Loading Loading @@ -1679,20 +1761,14 @@ int cam_hw_cdm_hang_detect( cdm_core = (struct cam_cdm *)cdm_hw->core_info; for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) mutex_lock(&cdm_core->bl_fifo[i].fifo_lock); for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) if (cdm_core->bl_fifo[i].work_record) { if (atomic_read(&cdm_core->bl_fifo[i].work_record)) { CAM_WARN(CAM_CDM, "workqueue got delayed, bl_fifo: %d, work_record :%u", i, cdm_core->bl_fifo[i].work_record); "workqueue got delayed, work_record :%u", atomic_read(&cdm_core->bl_fifo[i].work_record)); rc = 0; break; } for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) mutex_unlock(&cdm_core->bl_fifo[i].fifo_lock); return rc; } Loading Loading @@ -1797,7 +1873,7 @@ int cam_hw_cdm_init(void *hw_priv, } for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) { cdm_core->bl_fifo[i].last_bl_tag_done = -1; cdm_core->bl_fifo[i].work_record = 0; atomic_set(&cdm_core->bl_fifo[i].work_record, 0); } rc = cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl); Loading Loading @@ -1856,6 +1932,7 @@ int cam_hw_cdm_deinit(void *hw_priv, &cdm_core->bl_fifo[i].bl_request_list, entry) { list_del_init(&node->entry); kfree(node); node = NULL; } } Loading Loading @@ -1931,13 +2008,16 @@ static int cam_hw_cdm_component_bind(struct device *dev, cdm_hw = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); if (!cdm_hw) { kfree(cdm_hw_intf); cdm_hw_intf = NULL; return -ENOMEM; } cdm_hw->core_info = kzalloc(sizeof(struct cam_cdm), GFP_KERNEL); if (!cdm_hw->core_info) { kfree(cdm_hw); cdm_hw = NULL; kfree(cdm_hw_intf); cdm_hw_intf = NULL; return -ENOMEM; } Loading Loading @@ -2174,11 +2254,15 @@ static int cam_hw_cdm_component_bind(struct device *dev, mutex_unlock(&cdm_hw->hw_mutex); release_private_mem: kfree(cdm_hw->soc_info.soc_private); cdm_hw->soc_info.soc_private = NULL; release_mem: mutex_destroy(&cdm_hw->hw_mutex); kfree(cdm_hw_intf); cdm_hw_intf = NULL; kfree(cdm_hw->core_info); cdm_hw->core_info = NULL; kfree(cdm_hw); cdm_hw = NULL; return rc; } Loading Loading @@ -2256,9 +2340,13 @@ static void cam_hw_cdm_component_unbind(struct device *dev, mutex_destroy(&cdm_hw->hw_mutex); kfree(cdm_hw->soc_info.soc_private); cdm_hw->soc_info.soc_private = NULL; kfree(cdm_hw_intf); cdm_hw_intf = NULL; kfree(cdm_hw->core_info); cdm_hw->core_info = NULL; kfree(cdm_hw); cdm_hw = NULL; } const static struct component_ops cam_hw_cdm_component_ops = { Loading
drivers/cam_cdm/cam_cdm_intf_api.h +37 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ #include "cam_cdm_util.h" #include "cam_soc_util.h" #define CAM_CDM_BL_CMD_MAX 25 /* enum cam_cdm_id - Enum for possible CAM CDM hardwares */ enum cam_cdm_id { CAM_CDM_VIRTUAL, Loading Loading @@ -151,6 +153,41 @@ struct cam_cdm_bl_request { struct cam_cdm_bl_cmd cmd[1]; }; /** * struct cam_cdm_bl_data - last submiited CDM BL data * * @mem_handle : Input mem handle of bl cmd * @hw_addr : Hw address of submitted Bl command * @offset : Input offset of the actual bl cmd in the memory pointed * by mem_handle * @len : length of submitted Bl command to CDM. * @input_len : Input length of the BL command, Cannot be more than 1MB and * this is will be validated with offset+size of the memory pointed * by mem_handle * @type : CDM bl cmd addr types. */ struct cam_cdm_bl_data { int32_t mem_handle; dma_addr_t hw_addr; uint32_t offset; size_t len; uint32_t input_len; enum cam_cdm_bl_cmd_addr_type type; }; /** * struct cam_cdm_bl_info * * @bl_count : No. of Bl commands submiited to CDM. * @cmd : payload holding the BL cmd's arrary * that is sumbitted. * */ struct cam_cdm_bl_info { int32_t bl_count; struct cam_cdm_bl_data cmd[CAM_CDM_BL_CMD_MAX]; }; /** * @brief : API to get the CDM capabilities for a camera device type * Loading
drivers/cam_cdm/cam_cdm_util.c +66 −12 Original line number Diff line number Diff line Loading @@ -689,25 +689,53 @@ int cam_cdm_util_cmd_buf_write(void __iomem **current_device_base, return ret; } static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_dmi_cmd(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { long ret = 0; struct cdm_dmi_cmd *p_dmi_cmd; uint32_t *temp_ptr = cmd_buf_addr; p_dmi_cmd = (struct cdm_dmi_cmd *)cmd_buf_addr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI]; CAM_INFO(CAM_CDM, "DMI"); if (temp_ptr > cmd_buf_addr_end) CAM_ERR(CAM_CDM, "Invalid cmd start addr:%pK end addr:%pK", temp_ptr, cmd_buf_addr_end); CAM_INFO(CAM_CDM, "DMI: LEN: %u DMIAddr: 0x%X DMISel: 0x%X LUT_addr: 0x%X", p_dmi_cmd->length, p_dmi_cmd->DMIAddr, p_dmi_cmd->DMISel, p_dmi_cmd->addr); return ret; } static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_buff_indirect(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { long ret = 0; struct cdm_indirect_cmd *p_indirect_cmd; uint32_t *temp_ptr = cmd_buf_addr; p_indirect_cmd = (struct cdm_indirect_cmd *)cmd_buf_addr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT]; CAM_INFO(CAM_CDM, "Buff Indirect"); if (temp_ptr > cmd_buf_addr_end) CAM_ERR(CAM_CDM, "Invalid cmd start addr:%pK end addr:%pK", temp_ptr, cmd_buf_addr_end); CAM_INFO(CAM_CDM, "Buff Indirect: LEN: %u addr: 0x%X", p_indirect_cmd->length, p_indirect_cmd->addr); return ret; } static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { long ret = 0; struct cdm_regcontinuous_cmd *p_regcont_cmd; Loading @@ -722,6 +750,12 @@ static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr) p_regcont_cmd->count, p_regcont_cmd->offset); for (i = 0; i < p_regcont_cmd->count; i++) { if (temp_ptr > cmd_buf_addr_end) { CAM_ERR(CAM_CDM, "Invalid cmd(%d) start addr:%pK end addr:%pK", i, temp_ptr, cmd_buf_addr_end); break; } CAM_INFO(CAM_CDM, "DATA_%d: 0x%X", i, *temp_ptr); temp_ptr++; Loading @@ -731,7 +765,8 @@ static long cam_cdm_util_dump_reg_cont_cmd(uint32_t *cmd_buf_addr) return ret; } static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { struct cdm_regrandom_cmd *p_regrand_cmd; uint32_t *temp_ptr = cmd_buf_addr; Loading @@ -746,6 +781,12 @@ static long cam_cdm_util_dump_reg_random_cmd(uint32_t *cmd_buf_addr) p_regrand_cmd->count); for (i = 0; i < p_regrand_cmd->count; i++) { if (temp_ptr > cmd_buf_addr_end) { CAM_ERR(CAM_CDM, "Invalid cmd(%d) start addr:%pK end addr:%pK", i, temp_ptr, cmd_buf_addr_end); break; } CAM_INFO(CAM_CDM, "OFFSET_%d: 0x%X DATA_%d: 0x%X", i, *temp_ptr & CAM_CDM_REG_OFFSET_MASK, i, *(temp_ptr + 1)); Loading Loading @@ -778,15 +819,22 @@ static long cam_cdm_util_dump_wait_event_cmd(uint32_t *cmd_buf_addr) return ret; } static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr) static long cam_cdm_util_dump_change_base_cmd(uint32_t *cmd_buf_addr, uint32_t *cmd_buf_addr_end) { long ret = 0; struct cdm_changebase_cmd *p_cbase_cmd; uint32_t *temp_ptr = cmd_buf_addr; p_cbase_cmd = (struct cdm_changebase_cmd *)temp_ptr; temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE]; ret += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE]; if (temp_ptr > cmd_buf_addr_end) CAM_ERR(CAM_CDM, "Invalid cmd start addr:%pK end addr:%pK", temp_ptr, cmd_buf_addr_end); CAM_INFO(CAM_CDM, "CHANGE_BASE: 0x%X", p_cbase_cmd->base); Loading Loading @@ -819,6 +867,7 @@ void cam_cdm_util_dump_cmd_buf( uint32_t *cmd_buf_start, uint32_t *cmd_buf_end) { uint32_t *buf_now = cmd_buf_start; uint32_t *buf_end = cmd_buf_end; uint32_t cmd = 0; if (!cmd_buf_start || !cmd_buf_end) { Loading @@ -834,16 +883,20 @@ void cam_cdm_util_dump_cmd_buf( case CAM_CDM_CMD_DMI: case CAM_CDM_CMD_DMI_32: case CAM_CDM_CMD_DMI_64: buf_now += cam_cdm_util_dump_dmi_cmd(buf_now); buf_now += cam_cdm_util_dump_dmi_cmd(buf_now, buf_end); break; case CAM_CDM_CMD_REG_CONT: buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now); buf_now += cam_cdm_util_dump_reg_cont_cmd(buf_now, buf_end); break; case CAM_CDM_CMD_REG_RANDOM: buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now); buf_now += cam_cdm_util_dump_reg_random_cmd(buf_now, buf_end); break; case CAM_CDM_CMD_BUFF_INDIRECT: buf_now += cam_cdm_util_dump_buff_indirect(buf_now); buf_now += cam_cdm_util_dump_buff_indirect(buf_now, buf_end); break; case CAM_CDM_CMD_GEN_IRQ: buf_now += cam_cdm_util_dump_gen_irq_cmd(buf_now); Loading @@ -852,7 +905,8 @@ void cam_cdm_util_dump_cmd_buf( buf_now += cam_cdm_util_dump_wait_event_cmd(buf_now); break; case CAM_CDM_CMD_CHANGE_BASE: buf_now += cam_cdm_util_dump_change_base_cmd(buf_now); buf_now += cam_cdm_util_dump_change_base_cmd(buf_now, buf_end); break; case CAM_CDM_CMD_PERF_CTRL: buf_now += cam_cdm_util_dump_perf_ctrl_cmd(buf_now); Loading