基于 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(); // ?...
Posts
Color Management drm_color_mgmt.c, drm_color_mgmt.h color management or color space 通过 drm_crtc 和 drm_plane 的相关 properties 来实现控制。 drm_crtc_enable_color_mgmt() 用来 create crtc 相关的 degamma lut, ctx, gamma lut 这些 properties,在 crtc 初始化过程中调用。 还有一个初始化函数 drm_mode_crtc_set_gamma_size() 可以用来 support legacy gamma 相关接口。 drm_plane_create_color_properties() create plane 相关的 yuv color coding, color range properties,在 plane 初始化过程中调用。 Properties 具体看 drm_crtc_state 和 drm_plane_state 中对应的 fields. crtc: DEGAMMA_LUT, DEGAMMA_LUT_SIZE, CTM, GAMMA_LUT, GAMMA_LUT_SIZE plane: COLOR_ENCODING, COLOR_RANGE Userspace 之后 userspace 可以通过设置这些 properties 修改到 struct drm_crtc_state 和 struct drm_plane_state 中相关的 fields....
DRM_IOCTL_MODE_ATOMIC struct drm_mode_atomic { __u32 flags; __u32 count_objs; __u64 objs_ptr; __u64 count_props_ptr; __u64 props_ptr; __u64 prop_values_ptr; __u64 reserved; __u64 user_data; }; app: flags: 可传入的 flags 参考 DRM_MODE_ATOMIC_FLAGS 宏,有 DRM_MODE_PAGE_FLIP_EVENT/DRM_MODE_PAGE_FLIP_ASYNC/DRM_MODE_ATOMIC_TEST_ONLY/DRM_MODE_ATOMIC_NONBLOCK/DRM_MODE_ATOMIC_ALLOW_MODESET. count_objs: 要设置的 drm object 数量。 objs_ptr: 要设置的 object id 数组指针。 count_props_ptr: 每个 object 要设置多少个 property 的数组指针。 props_ptr: 要设置的 property id 数组指针。 prop_values_ptr: 要设置的 property value 数组指针。 user_data: 用户传入的一个 data 指针值。 kernel:
struct drm_display_mode { /** * @clock: * * Pixel clock in kHz. */ int clock; /* in kHz */ u16 hdisplay; u16 hsync_start; u16 hsync_end; u16 htotal; u16 hskew; u16 vdisplay; u16 vsync_start; u16 vsync_end; u16 vtotal; u16 vscan; /** * @flags: * * Sync and timing flags: * * - DRM_MODE_FLAG_PHSYNC: horizontal sync is active high. * - DRM_MODE_FLAG_NHSYNC: horizontal sync is active low. * - DRM_MODE_FLAG_PVSYNC: vertical sync is active high....
人眼对亮度的感知是非线性的,对暗处的变化比亮处的变化更敏感。如果图像没有进行 gamma correction,那么会分配了太多的比特来突出人类无法区分的亮点,并且分配了太少的比特显示阴影。因此需要 gamma correction 来校准,尽量做到线性化。 可以想象 video out 和 video in 之间的公式: $V_{out} = V_{in}^\gamma$ if gamma < 1, encoding gamma,称作 gamma compression。 if gamma > 1, decoding gamma,称作 gamma expansion。 蓝色为输入图像亮度变化曲线,红色为 gamma 值的曲线,紫色为最终显示的亮度变化曲线。 display gamma 即 lcd 运用的 gamma 变换,可以看出 gamma 的值在比如 0~255 色深中不是一个定值,通常需要 LUT 查找表来对某一范围内的亮度进行 gamma 变换。在 0~255 低位区域使用更小的 gamma,而高位区域使用更大的 gamma 值,gamma > 1。
# modetest --help usage: modetest [-acDdefMPpsCvrw] Query options: -c list connectors -e list encoders -f list framebuffers -p list CRTCs and planes (pipes) Test options: -P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>] set a plane -s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>] set a mode -C test hw cursor -v test vsynced page flipping -r set the preferred mode for all connectors -w <obj_id>:<prop_name>:<value> set property -a use atomic API -F pattern1,pattern2 specify fill patterns Generic options: -d drop master after mode set -M module use the given driver -D device use the given device modetest -M rts_drm -a -r modetest -M rts_drm -a -s 51@47:320x240 -P 31@47:320x240 -F tiles -v # test vsync
private object dma fence
Aggregate Driver 实现结构体: struct component_master_ops { int (*bind)(struct device *master); void (*unbind)(struct device *master); }; 在 probe 函数中调用 component_match_add()来填充 component match list, 最后调用 component_master_add_with_match() register aggregate driver, remove 函数中调用 component_master_del() 来 unregister。 void component_match_add(struct device *parent, struct component_match **matchptr, int (*compare)(struct device*, void*), void *compare_data) int component_master_add_with_match(struct device *parent, const struct component_master_ops *ops, struct component_match *match) Components Driver 实现结构体: struct component_ops { int (*bind)(struct device *comp, struct device *master, void *master_data); void (*unbind)(struct device *comp, struct device *master, void *master_data); }; 在 probe 函数中调用 component_add() register component driver, remove 函数中调用 component_del() 来 ungister。...