1 ISP的中断类型
ISP中断类型
SOF: 一帧图像数据开始传输
EOF: 一帧图像数据传输完成
REG_UPDATE: ISP寄存器更新完成(每个reg group都有独立的这个中断)
EPOCH: ISP某一行结尾(默认20)就会产生此中断
BUFFER DONE: 一帧图像数据ISP完全写到DDR了
2 ISP驱动状态机
通过camera context ops来实现的。
具体包含两种状态机,1、state machine 2、substate machine
当处于state machine的active状态时,substate machine才会工作起来。
除了substate machine外,还有substate_machine_irq用来接收中断处理。
一个中断如何调用到substate_machine的操作集中,流程图如下图示:
概述:
1)csl中调用流程1
umd的csl中调用ioctl,调用到内核中cam_node,然后调用到cam_context, cam_context会根据状态机中的ioctl_ops设置,调用对应接口处理。
2)crm中调用流程2
crm处理req时,经过crm_node_intf调用到cam_node,然后调用到cam_context, 进而调用到状态机中crm_ops的相关函数。
3)收到irq处理流程3
当顶部状态机处于actived状态时,当isp中收到SOF中断时,irq经过ife_hw_mgr调用到cam_context, 进而调用到状态机中irq_ops, irq_ops会进一步调用到子状态机中irq_ops相关函数来处理。
3 Top State Machine
-
什么是顶部状态机?
cam_context中定义了几种状态,完成cam context中不同状态的轮转和不同流程处理。
umd中node调用kmd中cam context时,根据不同状态做不同处理。 -
调用入口:
当cam_isp_dev_component_bind时,会循环多次(如果是ife会循环8次)初始化cam_isp_context_init,
然后设置给cam context设置顶部状态机,定义如下
ctx_base->state_machine = cam_isp_ctx_top_state_machine;
3.1 状态机类型
/**
* enum cam_ctx_state - context top level states
*/
enum cam_context_state {
CAM_CTX_UNINIT = 0,
CAM_CTX_AVAILABLE = 1,
CAM_CTX_ACQUIRED = 2,
CAM_CTX_READY = 3,
CAM_CTX_FLUSHED = 4,
CAM_CTX_ACTIVATED = 5,
CAM_CTX_STATE_MAX = 6,
};
3.2 状态机如何流转
4 Activated Substate Machine
-
子状态机的用处?
只有在cam_ctx_activated时,子状态机才有效。这是isp的子状态,由isp中断来驱动状态机切换。来了不同中断,切换不同子状态,然后处理request,并且把request move到不同的list里,直到最后buffer done中断来了之后,把request从isp上下文中彻底移除,并且通知camera sync这个request的buffer 已经填好了。 -
入口,在哪里赋值的?
在cam_isp_context_init时,会设置子状态机和子状态机下的中断处理。
cam_isp_context_init()
ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
ctx->substate_machine = cam_isp_ctx_activated_state_machine;
ctx->substate_machine_irq = cam_isp_ctx_activated_state_machine_irq;
4.1 子状态机类型
/**
* enum cam_isp_ctx_activated_substate - sub states for activated
*
*/
enum cam_isp_ctx_activated_substate {
CAM_ISP_CTX_ACTIVATED_SOF,
CAM_ISP_CTX_ACTIVATED_APPLIED,
CAM_ISP_CTX_ACTIVATED_EPOCH,
CAM_ISP_CTX_ACTIVATED_BUBBLE,
CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED,
CAM_ISP_CTX_ACTIVATED_HW_ERROR,
CAM_ISP_CTX_ACTIVATED_HALT,
CAM_ISP_CTX_ACTIVATED_MAX,
};
struct cam_isp_ctx_irq_ops 定义了中断处理函数,他是根据子状态机当前状态找到对应处理接口。
static struct cam_isp_ctx_irq_ops
cam_isp_ctx_activated_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = {
/* SOF */
{
.irq_ops = {
__cam_isp_ctx_handle_error,
__cam_isp_ctx_sof_in_activated_state,
__cam_isp_ctx_reg_upd_in_sof,
__cam_isp_ctx_notify_sof_in_activated_state,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_sof,
__cam_isp_ctx_handle_secondary_events,
},
},
/* APPLIED */
{
.irq_ops = {
__cam_isp_ctx_handle_error,
__cam_isp_ctx_sof_in_activated_state,
__cam_isp_ctx_reg_upd_in_applied_state,
__cam_isp_ctx_epoch_in_applied,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_applied,
__cam_isp_ctx_handle_secondary_events,
},
},
/* EPOCH */
{
.irq_ops = {
__cam_isp_ctx_handle_error,
__cam_isp_ctx_sof_in_epoch,
__cam_isp_ctx_reg_upd_in_epoch_bubble_state,
__cam_isp_ctx_notify_sof_in_activated_state,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_epoch,
__cam_isp_ctx_handle_secondary_events,
},
},
/* BUBBLE */
{
.irq_ops = {
__cam_isp_ctx_handle_error,
__cam_isp_ctx_sof_in_activated_state,
__cam_isp_ctx_reg_upd_in_epoch_bubble_state,
__cam_isp_ctx_notify_sof_in_activated_state,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_bubble,
__cam_isp_ctx_handle_secondary_events,
},
},
/* Bubble Applied */
{
.irq_ops = {
__cam_isp_ctx_handle_error,
__cam_isp_ctx_sof_in_activated_state,
__cam_isp_ctx_reg_upd_in_applied_state,
__cam_isp_ctx_epoch_in_bubble_applied,
NULL,
__cam_isp_ctx_buf_done_in_bubble_applied,
__cam_isp_ctx_handle_secondary_events,
},
},
/* HW ERROR */
{
.irq_ops = {
NULL,
__cam_isp_ctx_sof_in_activated_state,
__cam_isp_ctx_reg_upd_in_hw_error,
NULL,
NULL,
NULL,
},
},
/* HALT */
{
},
};
4.2 子状态机如何流转
首先调用start_dev接口后,isp子状态机进入SOF状态。
分2种情况:
-
isp正常工作子状态切换
-
isp Bubble模式子状态切换