ISP中断类型
SOF: 一帧图像数据开始传输
EOF: 一帧图像数据传输完成
REG_UPDATE: ISP寄存器更新完成(每个reg group都有独立的这个中断)
EPOCH: ISP某一行结尾(默认20)就会产生此中断
BUFFER DONE: 一帧图像数据ISP完全写到DDR了
管理Isp request的几个List
struct cam_isp_context {
struct list_head active_req_list;//reg_upd中断将isp request保存到这里并等待buffer done中断
struct list_head pending_req_list;//umd submit的isp request保存到这里等待sof(epoch)时crm apply其到HW
struct list_head wait_req_list;//apply之后保存isp request到这个链表并且等待reg_upd中断
struct list_head free_req_list;//保存所有可用的isp request对象
}
Isp request在kernel里的生命周期图
Bubble Recovery
Isp bubble state request生命周期解析图
Isp bubble 恢复机制
cam_req_mgr_process_error(void *priv, void *data)
{
switch (err_info->error) {
case CRM_KMD_ERR_BUBBLE:
idx = __cam_req_mgr_find_slot_for_req(in_q, err_info->req_id);//在in_q中找到bubble request对应下标
__cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl);//让bubble这次遍历skip掉pd 1的request
in_q->rd_idx = idx;//重置rd_idx为bubble request对应的下标
slot_diff = in_q->last_applied_idx - idx;//计算出最新applied request到 发生bubble request的下标偏差
//把出现bubble request开始到last appiled之间的request都标为CRM_SLOT_STATUS_REQ_ADDED,
//这些request都需要在SOF/EOF来时重新配置到realtime HW
for (i = 0; i < slot_diff; i++) {
__cam_req_mgr_inc_idx(&idx, 1, link->req.l_tbl->num_slots);
if (in_q->slot[idx].status == CRM_SLOT_STATUS_REQ_APPLIED)
in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED;
}
__cam_req_mgr_apply_on_bubble(link, err_info);//立刻重新配置pd 2的设备的request到hw
}
}
正常流程:sof - applywithcf - Applied状态 - reg upd中断 - epoch状态 - bufdone中断
ISP bubble :Applied之后应该是reg upd 的中断,这时来了epoch中断,说明这张图无效,此时进入buffle状态,isp通知crm error
如果req5发生bubble,rd_idx会被移动到req5的位置,前面配置到ISP的5的buffer done不会返回到umd。等reapply到5的request,完成buffer done并且状态从bubble恢复之后才返回UMD。
req5在下一个SOF重新配置给ISP HW,如果这是bubbled req5 buf done还没到,就等下个sof再检查bubbled req5 buf done是否到达,到达就reapply req5到isp hw