基于 linux 6.6 drm api

注释掉的 api 表示暂时不关心,带 > 的 api 表示常常在 driver 中调用,其他都是在 drm internal 中内部调用,或不常使用。

drm_atomic_helper.c

drm_atomic_helper_check_modeset(); // drm_atomic_helper_check() 中调用
// drm_atomic_helper_check_wb_encoder_state();
drm_atomic_helper_check_plane_state(); // 在 plane atomic check 中调用
drm_atomic_helper_check_planes(); // drm_atomic_helper_check() 中调用
drm_atomic_helper_check_crtc_primary_plane(); // 检查 crtc 是否绑定了 primary plane。一般给 simple drm 只有一个 primary plane 的 driver 使用。
drm_atomic_helper_check(); // drm_mode_config_funcs->atomic_check 的 helper func
drm_atomic_helper_commit_tail(); // drm_mode_config_helper_funcs.atomic_commit_tail 的 helper 函数。
drm_atomic_helper_commit_tail_rpm(); // rpm 版本
drm_atomic_helper_commit(); // drm_mode_config_funcs->atomic_commit 的 helper 函数。
// drm_atomic_helper_async_check();
// drm_atomic_helper_async_commit();
drm_atomic_helper_wait_for_fences(); // ??? dma fence 相关
drm_atomic_helper_wait_for_vblanks(); // 在 drm_atomic_helper_commit_tail() 中调用
drm_atomic_helper_wait_for_flip_done(); // 可以代替 wait_for_vblanks. vendor driver 自行在 atomic commit 回调中调用,用于等待所有的 crtc 完成。
drm_atomic_helper_update_legacy_modeset_state(); // drm_atomic_helper_commit_modeset_disables() 中调用
drm_atomic_helper_calc_timestamping_constants(); // drm_atomic_helper_commit_modeset_disables() 中调用
drm_atomic_helper_commit_modeset_disables(); // drm_atomic_helper_commit_tail() 中调用
drm_atomic_helper_commit_modeset_enables(); // drm_atomic_helper_commit_tail() 中调用
drm_atomic_helper_prepare_planes(); // drm_atomic_helper_commit() 中调用
drm_atomic_helper_unprepare_planes(); // drm_atomic_helper_commit() 中调用
drm_atomic_helper_commit_planes(); // drm_atomic_helper_commit_tail() 中调用
drm_atomic_helper_cleanup_planes(); // drm_atomic_helper_commit_tail() 中调用
// drm_atomic_helper_commit_planes_on_crtc();
drm_atomic_helper_disable_planes_on_crtc(); // ??? 一些 vendor driver 在 crtc 的 atomic_disable 中调用来 disable planes
drm_atomic_helper_swap_state(); // drm_atomic_helper_commit() 中调用
drm_atomic_helper_setup_commit(); // drm_atomic_helper_commit() 中调用
drm_atomic_helper_wait_for_dependencies(); // drm_atomic_helper_commit() 中调用
drm_atomic_helper_fake_vblank(); // drm_atomic_helper_commit_tail() 中调用
drm_atomic_helper_commit_hw_done(); // drm_atomic_helper_commit_tail() 中调用
drm_atomic_helper_commit_cleanup_done(); // drm_atomic_helper_commit() 中调用

/* implementations for legacy interfaces */
drm_atomic_helper_update_plane(); // drm_plane_funcs->update_plane
drm_atomic_helper_disable_plane(); // drm_plane_funcs->disable_plane
drm_atomic_helper_set_config(); // drm_crtc_funcs->set_config
drm_atomic_helper_disable_all(); // 在 drm_atomic_helper_suspend() 和 drm_atomic_helper_shutdown() 中调用
drm_atomic_helper_shutdown();
drm_atomic_helper_duplicate_state(); // drm_atomic_helper_suspend() 中调用
drm_atomic_helper_suspend();
drm_atomic_helper_commit_duplicated_state(); // drm_atomic_helper_resume() 中调用
drm_atomic_helper_resume();
drm_atomic_helper_page_flip(); // drm_crtc_funcs->page_flip
// drm_atomic_helper_page_flip_target();

drm_atomic_crtc_for_each_plane();
drm_atomic_crtc_state_for_each_plane();
drm_atomic_crtc_state_for_each_plane_state();
drm_atomic_helper_bridge_propagate_bus_fmt();

如果 vendor driver 使用提供的 helper function drm_atomic_helper_check()drm_atomic_helper_commit(),那么其他的 helper function 大部分不需要 vendor driver 再去调用,除了:

  • drm_atomic_helper_check_plane_state()
  • drm_atomic_helper_disable_planes_on_crtc()

drm_atomic_helper_check_modeset: 在 drm_mode_config_funcs->atomic_check 中调用。检查 atomic state 是否是 physical possible 的。 如果在 plane 的 atomic_check 函数中设置了 mode_changed=true (表示 plane 的更新需要 full modeset,比如调整 pclk, 内存带宽等等),则需要再 plane check 之后再次调用该函数。

// TODO: add comments on each function

drm_atomic_state_helper.c

__drm_atomic_helper_crtc_state_reset(); // __drm_atomic_helper_crtc_reset() 中调用
__drm_atomic_helper_crtc_reset(); // vendor subclass drm_crtc_state 时,在 drm_crtc_funcs->reset 中调用
drm_atomic_helper_crtc_reset(); // vendor 直接使用 drm_crtc_state 时,drm_crtc_funcs->reset
__drm_atomic_helper_crtc_duplicate_state(); // vendor subclass drm_crtc_state 时,在 drm_crtc_funcs->atomic_duplicate_state 中调用
drm_atomic_helper_crtc_duplicate_state(); // vendor 直接使用 drm_crtc_state 时,drm_crtc_funcs->atomic_duplicate_state
__drm_atomic_helper_crtc_destroy_state(); // vendor subclass drm_crtc_state 时,在 drm_crtc_funcs->rts_crtc_atomic_destroy_state 中调用
drm_atomic_helper_crtc_destroy_state(); // vendor 直接使用 drm_crtc_state 时,drm_crtc_funcs->rts_crtc_atomic_destroy_state

__drm_atomic_helper_plane_state_reset(); // __drm_atomic_helper_plane_reset 中调用
__drm_atomic_helper_plane_reset(); // vendor subclass drm_plane_state 时,在 drm_plane_funcs->reset 中调用
drm_atomic_helper_plane_reset(); // vendor 直接使用 drm_plane_state 时,drm_plane_funcs->reset
__drm_atomic_helper_plane_duplicate_state(); // 同上
drm_atomic_helper_plane_duplicate_state(); // 同上
__drm_atomic_helper_plane_destroy_state(); // 同上
drm_atomic_helper_plane_destroy_state(); // 同上

__drm_atomic_helper_connector_state_reset(); // 同上
__drm_atomic_helper_connector_reset(); // 同上
drm_atomic_helper_connector_reset(); // 同上
// drm_atomic_helper_connector_tv_reset();
// drm_atomic_helper_connector_tv_check();
// drm_atomic_helper_connector_tv_margins_reset();
__drm_atomic_helper_connector_duplicate_state(); // 同上
drm_atomic_helper_connector_duplicate_state(); // 同上
__drm_atomic_helper_connector_destroy_state(); // 同上
drm_atomic_helper_connector_destroy_state(); // 同上

__drm_atomic_helper_private_obj_duplicate_state(); // 同上

__drm_atomic_helper_bridge_duplicate_state(); // 同上
drm_atomic_helper_bridge_duplicate_state(); // 同上
drm_atomic_helper_bridge_destroy_state(); // 同上
__drm_atomic_helper_bridge_reset(); // 同上
drm_atomic_helper_bridge_reset(); // 同上

drm_atomic.c

drm_crtc_commit_get()
drm_crtc_commit_put()

drm_atomic_state_alloc();
drm_atomic_state_clear();
drm_atomic_state_get()
drm_atomic_state_put()
drm_atomic_state_init();
drm_atomic_state_default_clear();
drm_atomic_state_default_release();

drm_atomic_get_crtc_state();
drm_atomic_get_plane_state();
drm_atomic_get_connector_state();

drm_atomic_private_obj_init();
drm_atomic_private_obj_fini();

drm_atomic_get_private_obj_state();
drm_atomic_get_old_private_obj_state();
drm_atomic_get_new_private_obj_state();

drm_atomic_get_old_connector_for_encoder();
drm_atomic_get_new_connector_for_encoder();
drm_atomic_get_old_crtc_for_encoder();
drm_atomic_get_new_crtc_for_encoder();

drm_atomic_get_existing_crtc_state();
drm_atomic_get_old_crtc_state();
drm_atomic_get_new_crtc_state();
// same for plane/connector

vendor driver 会使用的 api 有:

  • drm_atomic_get_crtc/plane/connector/private_obj_state
  • drm_atomic_private_obj_init/fini

drm_auth.c

drm_master_get();
drm_file_get_master();
drm_master_put();
drm_is_current_master();
drm_master_create();

drm_blend.c

drm_rotation_90_or_270(); // 判断 rotation 是否为 90 or 270 度
drm_plane_create_alpha_property(); // 创建 plane alpha 属性
drm_plane_create_rotation_property(); // 创建 plane rotation 属性
drm_rotation_simplify(); // 排除 plane 不支持的 rotation
drm_plane_create_zpos_property();  // 创建 plane zpos 属性
drm_plane_create_zpos_immutable_property(); // 创建 plane immutable zpos 属性
drm_atomic_normalize_zpos(); // 把 userspace 设置的 zpos 统一到 0~N-1, N 为 planes 的数量。
drm_plane_create_blend_mode_property(); // 创建 plane blend mode 属性

drm_bridge_connector.c

> drm_bridge_connector_init();

注册 connector.

drm_bridge.c

drm_bridge_add()/drm_bridge_remove(); // 加入/删除 bridge list, 在 bridge driver 中调用
devm_drm_bridge_add();
drm_bridge_attach(); // attach bridge 到 encoder/previous bridge, 在 bridge driver/vendor driver 中调用
of_drm_find_bridge(); // 
drm_bridge_get_next_bridge()/drm_bridge_get_prev_bridge();
drm_bridge_chain_get_first_bridge();
drm_for_each_bridge_in_chain();
drm_bridge_chain_mode_fixup();
drm_bridge_chain_mode_valid();
drm_bridge_chain_mode_set();
drm_atomic_bridge_chain_check();
drm_atomic_bridge_chain_enable()/drm_atomic_bridge_chain_disable();
drm_atomic_bridge_chain_post_disable();
drm_atomic_bridge_chain_pre_enable();
drm_atomic_helper_bridge_propagate_bus_fmt();
drm_bridge_detect();
drm_bridge_get_modes();
drm_bridge_edid_read();
drm_bridge_get_edid();
drm_bridge_hpd_enable()/drm_bridge_hpd_disable();
drm_bridge_hpd_notify();
drm_bridge_is_panel();
drm_panel_bridge_add()/drm_panel_bridge_remove();
drm_panel_bridge_add_typed();
drm_panel_bridge_set_orientation();
devm_drm_panel_bridge_add();
devm_drm_panel_bridge_add_typed();
drmm_panel_bridge_add();
drm_panel_bridge_connector();
devm_drm_of_get_bridge();
drmm_of_get_bridge();

drm_client_modeset.c

drm_client.c

drm_color_mgmt.c

drm_color_lut_extract();
// drm_color_ctm_s31_32_to_qm_n();
drm_crtc_enable_color_mgmt();
drm_mode_crtc_set_gamma_size();
drm_color_lut_size();
drm_plane_create_color_properties();
drm_color_lut_check();

drm_connector.c

drm_crtc_helper.c

该文件中的 api 大部分都不是给 atomic driver 使用的。

drm_crtc_helper_atomic_check(); // crtc atomic_check 的 helper 函数

drm_crtc.c

> drm_crtc_from_index(); // 获取指定 index 的 crtc
> drm_crtc_init_with_planes();
> drm_crtc_cleanup();
> drmm_crtc_init_with_planes();
> drmm_crtc_alloc_with_planes();
> drm_crtc_mask(); // 返回当前 crtc 的 index mask
> drm_for_each_crtc();
// drm_for_each_crtc_reverse();
// drm_crtc_create_scaling_filter_property();

drm_damage_helper.c

drm_debugfs.c

> drm_debugfs_create_files();
> drm_debugfs_remove_files();
> drm_debugfs_add_file();
> drm_debugfs_add_files();

drm_debugfs_create_files (传统方式)
立即创建:调用时立即在指定的 debugfs 目录中创建文件
作用域:与 drm_minor 绑定,每个 minor 都有独立的文件
生命周期管理:需要手动管理,调用 drm_debugfs_remove_files 清理

drm_debugfs_add_files (现代方式)
延迟创建:添加到待创建列表,在 drm_debugfs_init 时统一创建
作用域:与 drm_device 绑定,设备级别的调试文件
生命周期管理:自动管理,使用 drmm_kzalloc 分配,设备销毁时自动清理

优先使用 drm_debugfs_add_files:现代化的接口,自动内存管理

仅在需要自定义目录结构时使用 drm_debugfs_create_files:需要特殊的 debugfs 层次结构

drm_drv.c

> devm_drm_dev_alloc();/drm_dev_alloc();
> drm_dev_register();/drm_dev_unregister();
> drm_dev_get();drm_dev_put();
drm_put_dev(); // drm_dev_unregister() + drm_dev_put()
> drm_dev_enter();/drm_dev_exit(); // device critical section, 如果 unplugged 状态,直接返回
> drm_dev_unplug();
drm_dev_is_unplugged();
> drm_firmware_drivers_only();
drm_core_check_feature();
drm_drv_uses_atomic_modeset();

drm_encoder.c

> drm_encoder_init();
> drmm_encoder_init();
> drmm_encoder_alloc();
drmm_plain_encoder_alloc();
drm_encoder_index();
> drm_encoder_mask();
drm_encoder_crtc_ok();
drm_encoder_find();
> drm_encoder_cleanup();
> drm_for_each_encoder_mask();
> drm_for_each_encoder();

drm_fb_dma_helper.c

drm_fb_helper.c

drm_fbdev_dma.c

drm_fbdev_generic.c

drm_file.c

drm_flip_work.c

drm_format_helper.c

drm_fb_clip_offset(); // 返回 clipping rectangle 的左顶点在 framebuffer 中的 offset
drm_fb_memcpy();
drm_fb_swab();
drm_fb_xrgb8888_to_rgb332();
drm_fb_xrgb8888_to_rgb565();
drm_fb_xrgb8888_to_xrgb1555();
drm_fb_xrgb8888_to_argb1555();
drm_fb_xrgb8888_to_rgba5551();
drm_fb_xrgb8888_to_rgb888();
drm_fb_xrgb8888_to_argb8888();
drm_fb_xrgb8888_to_xrgb2101010();
drm_fb_xrgb8888_to_argb2101010();
drm_fb_xrgb8888_to_gray8();
drm_fb_blit();
drm_fb_xrgb8888_to_mono();
drm_fb_build_fourcc_list();

这些变换函数,一般是给 mipi dbi 屏用的。

drm_fourcc.c

drm_format_info();
drm_get_format_info();
// drm_mode_legacy_fb_format();
// drm_driver_legacy_fb_format();
drm_format_info_block_width();
drm_format_info_block_height();
drm_format_info_bpp();
drm_format_info_min_pitch();

drm_prime.c

drm_plane.c

drm_plane_state_src();/drm_plane_state_dst();
> drm_universal_plane_init();
> drm_plane_cleanup();
> drmm_universal_plane_alloc();
> drm_plane_index();
> drm_plane_mask();
drm_plane_from_index();
drm_plane_force_disable();
drm_mode_plane_set_obj_prop();
drm_plane_find();
> drm_for_each_plane_mask();
> drm_for_each_plane();
drm_any_plane_has_format();
drm_plane_enable_fb_damage_clips();
drm_plane_get_damage_clips_count();
drm_plane_get_damage_clips();
drm_plane_create_scaling_filter_property();

drm_print.c

drm_info();
drm_notice();
drm_warn();
drm_err();
drm_info_once();
drm_notice_once();
drm_warn_once();
drm_err_once();

drm_probe_helper.c

drm_helper_probe_single_connector_modes();
drm_kms_helper_poll_init();/drm_kms_helper_poll_fini();
drm_helper_hpd_irq_event();
drm_connector_helper_hpd_irq_event();
drm_kms_helper_hotplug_event();
drm_kms_helper_connector_hotplug_event();
drm_kms_helper_poll_enable();drm_kms_helper_poll_disable();
drm_kms_helper_poll_reschedule();
drm_kms_helper_is_poll_worker();
// drm_crtc_helper_mode_valid_fixed();
// drm_connector_helper_get_modes_from_ddc();
// drm_connector_helper_get_modes_fixed();
// drm_connector_helper_get_modes();
// drm_connector_helper_tv_get_modes();

drm_property.c

drm_property_create();/drm_property_destroy();
> drm_property_create_enum();
> drm_property_create_bitmask();
> drm_property_create_range();
> drm_property_create_signed_range();
drm_property_create_object();
drm_property_create_bool();
> drm_property_add_enum();
> drm_property_create_blob();
> drm_property_blob_get();/drm_property_blob_put();
drm_property_lookup_blob();
drm_property_replace_global_blob();
> drm_property_replace_blob();

drm_rect.c

drm_rect_intersect();
drm_rect_clip_scaled();
drm_rect_calc_hscale();/drm_rect_calc_vscale();
drm_rect_rotate();
drm_rect_rotate_inv();

drm_simple_kms_helper.c

drm_simple_encoder_init();
drmm_simple_encoder_alloc();
drm_simple_display_pipe_attach_bridge();
drm_simple_display_pipe_init();

drm_syncobj.c

drm_vblank_work.c

drm_vblank.c

> drm_vblank_init();
drm_dev_has_vblank();
drm_crtc_vblank_count(); // 返回 software vblank counter
drm_crtc_vblank_count_and_time(); // 返回 software vblank counter 和该 counter 对应的 timestamp. 和 drm_vblank_count_and_times() 作用一样
drm_crtc_next_vblank_start(); // 计算下一帧开始的 timestamp
> drm_crtc_send_vblank_event(); // 向用户层发送 vblank event.
> drm_crtc_arm_vblank_event(); // 为一个 vblank interrupt 准备 vblank event. 注意,要使用这个函数,vblank interrupt 的发生必须是可控的。不能在 atomic commit hardware 和该函数调用中间发生 vblank interrupt,否则会产生竞态条件。如果硬件不支持这样的特性,那么需要在 isr 中通过 drm_crtc_send_vblank_event() 来手动发送 event。
drm_handle_vblank(); // legacy version of drm_crtc_handle_vblank()
> drm_crtc_handle_vblank(); // 
> drm_crtc_vblank_get();
> drm_crtc_vblank_put();
drm_wait_one_vblank();
drm_crtc_wait_one_vblank();
drm_crtc_vblank_off();
drm_crtc_vblank_reset();
drm_crtc_vblank_on();
drm_crtc_accurate_vblank_count();
drm_crtc_vblank_restore();
drm_calc_timestamping_constants();
drm_crtc_vblank_waitqueue();
drm_crtc_set_max_vblank_count();