dispc的中断处理

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  即可开启中断功能


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值