分析amdgpu display 的 irq service

分析irq service

dal: Data Access Layer 数据访问层

  1. 在irq_service中的irq_service_interface.h头文件中可以看出,irq_service是向外提供中断源操作函数函数,在内部实现寄存器操作
    
  2. 在irq_service.h又知道这个头文件是让client进行数据注册
    

以上,我们就可以了解到。irq_service想为了以后实现一个中间层,抽象出后续寄存器操作。

中断的操作,其主要分dal_irq_service_set,dal_irq_service_ack,dal_irq_service_to_irq_source

  • dal_irq_service_set设置对应的source是不是enbale
  • dal_irq_service_ack获取对应source有没有触发
  • dal_irq_service_to_irq_source 通过中断处理函数,知道对应的中断source是谁

初始化以dal_irq_service_dce110_create为例
dal_irq_service_dce110_create注册了info,info是存储service对应的结构体数组const struct irq_source_info
这个info的大小是可变长,目的是最大个数是和dc_irq_source这个枚举对应的
当我们注册了我们的info到irq_service.我们在dm中的动作基本完事了,剩下的就是对接amdgpu_ih部分的中断了
列举部分irq_service相关的代码

enum dc_irq_source {
....
....//总共多少个中断源的寄存器info
};
enum dc_irq_source dal_irq_service_to_irq_source(
        struct irq_service *irq_service,
        uint32_t src_id,
        uint32_t ext_id)
{
    return irq_service->funcs->to_dal_irq_source(
        irq_service,
        src_id,
        ext_id);
}

bool dal_irq_service_set(
    struct irq_service *irq_service,
    enum dc_irq_source source,
    bool enable)
{
    const struct irq_source_info *info =
        find_irq_source_info(irq_service, source);

    if (!info) {
        DC_LOG_ERROR("%s: cannot find irq info table entry for %d\n",
            __func__,
            source);
        return false;
    }

    dal_irq_service_ack(irq_service, source);

    if (info->funcs->set)
        return info->funcs->set(irq_service, info, enable);

    dal_irq_service_set_generic(irq_service, info, enable);

    return true;
}

//amdgpu_dm 层进行注册ih处理服务
static int amdgpu_dm_irq_handler(struct amdgpu_device *adev,
                 struct amdgpu_irq_src *source,
                 struct amdgpu_iv_entry *entry)

//中断souce信息返回
static const struct irq_service_funcs irq_service_funcs_dce110 = {
        .to_dal_irq_source = to_dal_irq_source_dce110
};

//初始化中断info和中断信息处理函数
static void construct(struct irq_service *irq_service,
              struct irq_service_init_data *init_data)
{
    dal_irq_service_construct(irq_service, init_data);

    irq_service->info = irq_source_info_dce110;
    irq_service->funcs = &irq_service_funcs_dce110;
}
//中断info的寄存器信息
static const struct irq_source_info
irq_source_info_dce110[DAL_IRQ_SOURCES_NUMBER] = {
    [DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
    hpd_int_entry(0),
    hpd_int_entry(1),
    hpd_int_entry(2),
    hpd_int_entry(3),
    hpd_int_entry(4),
    hpd_int_entry(5),
    hpd_rx_int_entry(0),
......处理函数和访问寄存器,如果没有set函数就使用通用寄存器,如果有则使用set多好,这他没实现好
}

//dc  core对外关于irq的操作

enum dc_irq_source dc_interrupt_to_irq_source(
        struct dc *dc,
        uint32_t src_id,
        uint32_t ext_id)
{
    return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id);
}

bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
{

    if (dc == NULL)
        return false;

    return dal_irq_service_set(dc->res_pool->irqs, src, enable);
}

void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
{
    dal_irq_service_ack(dc->res_pool->irqs, src);
}


//dm中对irq_service(dc core)的访问接口
dm_set_vblank
剩下的都是在drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c中

开始讲一下amdgpu_dm_irq的处理了

dm的irq处理,将irq分为两档, high,low
/* the number of contexts may be expanded in the future based on needs */

enum dc_interrupt_context {
    INTERRUPT_LOW_IRQ_CONTEXT = 0,
    INTERRUPT_HIGH_IRQ_CONTEXT,
    INTERRUPT_CONTEXT_NUMBER
};

high是需要立即进行相应的,low就在work中进行处理了
amdgpu_dm_irq_handler 是总的对接ih的处理processor
其中的代码就是对应的处理方式。
amdgpu_dm.c通过调用amdgpu_dm_irq_register_interrupt注册high和low的处理。

case INTERRUPT_LOW_IRQ_CONTEXT:
handle_hpd_irq()
handle_hpd_rx_irq()

case INTERRUPT_HIGH_IRQ_CONTEXT:
dm_crtc_high_irq()     //vblank
dm_pflip_high_irq()    //pflip  ---头疼,整了好几层
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值