Sprdfb_dispc.c (kernel\drivers\video\sc8825)
//注册中断处理函数结构
static inline int __must_check
request_irq( unsigned int irq, //中断号
irq_handler_t handler, //中断处理函数
unsigned long flags, //中断标志,上升沿,下降沿等
const char *name, //名字
void *dev ) //指针
//dispc的中断注册:
request_irq(IRQ_DISPC_INT, dispc_isr, IRQF_DISABLED, "DISPC", &dispc_ctx);
//dispc的中断服务程序:
static irqreturn_t dispc_isr(int irq, void *data)
{
//...
//SPRDFB_PANEL_IF_DPI 表示video_mode, SPRDFB_PANEL_IF_EDPI表示 cmd_mode
//mipi支持video_mode和cmd_mode, 读取id用的是cmd_mode
if((reg_val & 0x10) && (SPRDFB_PANEL_IF_DPI == dev->panel_if_type)) // vide mode /*dispc update done isr*/
{
printk("****** sprdfb:[%s] ****** refresh interrupt happened ******\n",__FUNCTION__);
dispc_write(0x10, DISPC_INT_CLR); //清除中断标志位
done = true;
}
else if ((reg_val & 0x1) && (SPRDFB_PANEL_IF_DPI != dev->panel_if_type)) //cmd mode
{ /* dispc done isr */
dispc_write(1, DISPC_INT_CLR);
dispc_ctx->is_first_frame = false;
done = true;
}
if((reg_val & 0x2) && (SPRDFB_PANEL_IF_DPI == dev->panel_if_type)) /*dispc external TE isr*/
{
dispc_write(0x2, DISPC_INT_CLR); //清除中断标志位
if(0 != dev->esd_te_waiter)
{
//Sprdfb_panel.c (kernel\drivers\video\sc8825) "sprdfb_panel_ESD_check()" 调用 dev->esd_te_done =1;
wake_up_interruptible_all(&(dev->esd_te_queue));
dev->esd_te_waiter = 0;
}
}
//...
}
//我们的代码中默认是不使用TE中断的,假如要使用此中断控制一些东西,可以这样做:
static irqreturn_t dispc_isr(int irq, void *data)
{
//...
if((reg_val & 0x2) && (SPRDFB_PANEL_IF_DPI == dev->panel_if_type)) /*dispc external TE isr*/
{
printk("****** sprdfb:[%s] ****** TE interrupt happened ******\n",__FUNCTION__);
dispc_clear_bits(BIT(1), DISPC_INT_EN); //disable interrupt 中断disable
dispc_write(0x2, DISPC_INT_CLR); //clear interrupt status 中断状态清0
func(); //调用自己的想要执行的函数,注意不要时间太长
}
//...
}
//方式一:在自己的sys接口中,show或者store函数中,可以加入以下函数:
dispc_set_bits(BIT(1), DISPC_INT_EN); //使能TE中断, 当TE中断来临时,就会调用上述的中断处理函数
//方式二:可以通过lookat设置寄存器,充当上述函数的功能
#define DISPC_INT_EN (0x0070)
static inline void dispc_set_bits(uint32_t bits, uint32_t reg)
{
dispc_write(dispc_read(reg) | bits, reg);
}
static inline uint32_t dispc_read(uint32_t reg)
{
return __raw_readl(DISPC_CTL_BEGIN + reg);
}
#define DISPC_CTL_BEGIN 0x21000000 //DISPC Registers
通过一层层代码剖析可以得出该寄存器:0x21000000+0x0070 = 0x21000070 的bit1写上1
查看 0x21000070 的内容: lookat -l 1 0x21000070
得出值为: 0x00000014, bit1位置为1 = 0x00000016
再通过: lookat -s 16 0x21000070 即可开启中断功能