MTK Linux DRM分析(三十)- MTK mtk_dsi.c(Part.2)
一、代码分析
函数主要涉及MediaTek DSI(显示串行接口)驱动的中断处理、电源管理、低功耗模式(ULPS)切换、显示模式切换以及DSI初始化配置。每个函数的分析将涵盖其作用、实现逻辑及在DSI驱动中的应用场景。
1. mtk_dsi_irq_status
功能说明: 处理DSI中断状态,响应各种中断事件(如缓冲区下溢、帧完成、TE信号等),并执行相应的动作(如触发AEE、唤醒等待队列、处理Vblank等)。
参数:
- int irq:中断号。
- void *dev_id:DSI控制器结构体(struct mtk_dsi *dsi)。
返回值:
- irqreturn_t:中断处理结果(IRQ_NONE 表示无中断,IRQ_HANDLED 表示已处理)。
实现细节:
- 检查有效性:验证DSI结构体和时钟状态,若无效返回 IRQ_NONE。
- 读取中断状态:从 DSI_INTSTA 寄存器读取中断状态(status)。
- 中断类型处理:
- 缓冲区下溢(BUFFER_UNDERRUN_INT_FLAG):
- 如果未强制高优先级(force_high_step == 0),记录下溢事件。
- 使用限速机制(mmp_rate)记录MMP事件。
- 如果满足触发条件(时间间隔大于10秒),触发AEE(异常事件处理),打印错误信息并记录时间戳。
- 调用 mtk_drm_crtc_analysis 和 mtk_drm_crtc_dump 进行CRTC分析和转储。
- 禁用下溢中断,设置恢复标志(need_recover)。
- 其他中断:根据DSI组件ID(DSI0/DSI1)记录MMP事件。
- 缓冲区下溢(BUFFER_UNDERRUN_INT_FLAG):
- 清除中断:保留 LPRX_RD_RDY_INT_FLAG 和 VM_CMD_DONE 位,清除其他中断状态。
- 具体中断处理:
- SLEEPOUT_DONE_INT_FLAG:唤醒 exit_ulps_done 等待队列。
- SLEEPIN_ULPS_DONE_INT_FLAG:唤醒 enter_ulps_done 等待队列。
- TE_RDY_INT_FLAG(命令模式):
- 记录TE信号时间戳,更新帧率上下文(lcm_fps_ctx_update)。
- 支持OPLUS特性(如TE检查、指纹识别、ADFR动态刷新率)。
- 触发CRTC的Vblank中断(根据 doze_delay 或 skip_vblank 参数控制频率)。
- 唤醒 te_rdy 等待队列(如果启用HBM)。
- FRAME_DONE_INT_FLAG(视频模式):
- 记录帧完成事件,触发Vblank中断。
- 支持OPLUS特性(如ADFR帧完成处理、指纹识别)。
- CMD_DONE_INT_FLAG:记录命令完成事件。
- 日志和跟踪:使用 DDPIRQ 和 drm_trace_tag_mark 记录中断信息。
- 时钟管理:调用 mtk_drm_top_clk_isr_put 释放时钟引用。
- 用途:处理DSI硬件中断,确保显示驱动对硬件事件的及时响应。
2. mtk_dsi_irq
功能说明: 处理DSI中断,聚焦于特定的中断标志(如接收就绪、命令完成、虚拟命令完成),并唤醒等待队列。
参数:
- int irq:中断号。
- void *dev_id:DSI控制器结构体(struct mtk_dsi *dsi)。
返回值:
- irqreturn_t:IRQ_HANDLED 表示中断已处理。
实现细节:
- 读取 DSI_INTSTA 寄存器,检查特定中断标志(LPRX_RD_RDY_INT_FLAG、CMD_DONE_INT_FLAG、VM_DONE_INT_FLAG)。
- 如果存在中断:
- 循环设置 DSI_RACK 的 RACK 位,直到DSI不再忙碌(DSI_BUSY 清零)。
- 清除中断状态(DSI_INTSTA)。
- 使用 mtk_dsi_irq_data_set 记录中断标志。
- 唤醒 irq_wait_queue 等待队列。
- 用途:处理特定DSI中断,确保命令和数据传输的同步。
3. mtk_dsi_poweroff
功能说明: 关闭DSI控制器电源,禁用时钟和物理层。
参数:
- struct mtk_dsi *dsi:DSI控制器结构体。
返回值:
- 无(void)。
实现细节:
- 检查时钟引用计数(clk_refcnt),若为0则打印错误并返回。
- 减少引用计数,若非0则直接返回。
- 在正常显示阶段(DISP_HELPER_STAGE_NORMAL):
- 禁用引擎时钟(engine_clk)和数字时钟(digital_clk)。
- 停止DSI(DSI_START 置0)。
- 清零命令队列寄存器(reg_cmdq0_ofs)。
- 关闭PHY层电源(phy_power_off)。
- 同步释放电源管理(pm_runtime_put_sync)。
- 如果存在OPLUS面板扩展函数(panel_poweroff),调用以关闭面板电源。
- 用途:安全关闭DSI硬件,降低功耗。
4. mtk_dsi_enter_ulps
功能说明: 使DSI进入超低功耗状态(Ultra-Low Power State, ULPS)。
参数:
- struct mtk_dsi *dsi:DSI控制器结构体。
返回值:
- 无(void)。
实现细节:
- 重置 enter_ulps_done 等待队列。
- 配置中断使能(SLEEPIN_ULPS_DONE_INT_FLAG)。
- 禁用高速时钟(LC_HS_TX_EN 置0)。
- 设置ULPS模式(LDX_ULPM_AS_L0、LD0_ULPM_EN、LC_ULPM_EN)。
- 等待 enter_ulps_done 事件(超时2秒)。
- 检查结果:
- 如果成功,打印调试信息。
- 如果失败,检查中断状态并打印错误或转储DSI状态。
- 重置相关寄存器设置,关闭MIPI TX预配置,启用软件控制。
- 将通道数置0(DSI_TXRX_CTRL 的 LANE_NUM)。
- 用途:进入低功耗模式,节省能耗。
5. mtk_dsi_exit_ulps
功能说明: 使DSI退出超低功耗状态(ULPS)。
参数:
- struct mtk_dsi *dsi:DSI控制器结构体。
返回值:
- 无(void)。
实现细节:
- 重置PHY层(mtk_dsi_phy_reset)。
- 配置MIPI TX预输出使能(pre_oe_config)。
- 重置 exit_ulps_done 等待队列。
- 配置中断使能(SLEEPOUT_DONE_INT_FLAG)。
- 设置ULPS退出模式(LDX_ULPM_AS_L0、SLEEP_MODE、SLEEPOUT_START)。
- 计算唤醒周期(wake_up_prd)并写入 DSI_TIME_CON0。