kms框架

KMS(Kernel Mode Setting)的框架如下,用户空间使用双framebuffer机制,分别对应两个plane对象。plane从drm_framebuffer获取显示数据。然后plane传送给crtc(lcdif控制器),经过编码后再送给显示屏(connector)进行显示。一般来说现在的soc都在lcdif外围设计了bridge ip来实现诸如mipi、lvds和hdmi的功能。这里芯片已经实现的bridge就是我们这里的drm encoder(显示编码器)。而在encoder下面外接转换芯片称为 drm bridge。

原子状态

atomic提供了modeset事务更新集,和尝试提交和回滚的事务不同的是:

①提交失败时不允许更改硬件状态。

②允许设置和回滚软件状态。

整体的原子状态分为成了plane,crtc和connector(drm_plane_state/drm_crtc_state/drm_connector_state)。用户空间可以查看并修改这三个对象的原子状态。只有当状态被提交时,它才会应用于驱动程序和modeset集对象。这种方式回滚更新归结为释放内存取消引用像帧缓冲区这样的对象。

帧缓冲

应用程序通过 DRM_IOCTL_MODE_ADDFB ioctl 显式请求创建帧缓冲区,并接收可以传递给 KMS CRTC 控制、plane配置和flip功能的不透明句柄。

帧缓冲区依赖底层内存管理器来分配后备存储。创建帧缓冲区时,应用程序通过参数传递内存句柄(或多平面格式的内存句柄列表) 。对于使用 GEM 作为其用户空间缓冲区管理接口的驱动程序,这将是一个 GEM 句柄。基于 GEM 的驱动程序应调用drm_gem_handle_create()以创建句柄。用户空间可以通过这个dirty回调通知驱动程序帧缓冲区的一个区域已经改变并且应该被刷新到显示硬件。

drm 帧缓冲区的生命周期由引用计数控制,驱动程序可以使用 drm_framebuffer_get()获取其他引用,并使用drm_framebuffer_put()再次删除它们。

struct drm_framebuffer {
  struct drm_device *dev;帧缓冲区所属的 DRM 设备
  struct list_head head;
  struct drm_mode_object base;
  char comm[TASK_COMM_LEN];
  const struct drm_format_info *format;//帧缓冲格式信息
  const struct drm_framebuffer_funcs *funcs;//帧缓冲 func 表
  unsigned int pitches[DRM_FORMAT_MAX_PLANES];//每个缓冲区的行步长。对于用户空间创建的对象,这是从 drm_mode_fb_cmd2 复制的。
  unsigned int offsets[DRM_FORMAT_MAX_PLANES];//每个缓冲区从缓冲区开始到实际像素数据的偏移量(以字节为单位)。
  uint64_t modifier;//数据布局修饰符。这用于描述平铺或辅助缓冲区的特殊布局(如压缩)。
  unsigned int width;
  unsigned int height;
  int flags;
  int hot_x;
  int hot_y;
  struct list_head filp_head;
  struct drm_gem_object *obj[DRM_FORMAT_MAX_PLANES];//支持帧缓冲区的 GEM 对象,每个平面一个。
};

请注意,offset这是一个线性偏移,不考虑每个修改器的平铺或缓冲层。当这个帧缓冲平面的实际像素数据从一个偏移量开始时使用它,例如,当在同一个后备存储缓冲区对象中分配多个平面时。对于平铺布局,这通常意味着它 的偏移量必须至少与平铺大小对齐,但硬件通常有更严格的要求。

这不应该用于将 x/y 像素偏移指定到缓冲区数据中(即使对于线性缓冲区)。指定 x/y 像素偏移是通过drm_plane_state。

plane

平面表示可以在扫描输出过程中与 CRTC 混合或覆盖在其顶部的图像源。plane从drm_framebuffer中获取输入数据。plane本身应该指定该图像的裁剪和缩放,以及可见区域的放置位置,还应指定像素如何混合和定位,如z位置/旋转。

每个 CRTC 必须有一个唯一的主平面用户空间可以附加以启用 CRTC。换句话说,用户空间必须能够同时将不同的主平面附加到每个 CRTC。主平面仍然可以与多个 CRTC 兼容。主平面的数量必须与 CRTC 的数量完全相同。

struct drm_plane_state {
  struct drm_plane *plane;
  struct drm_crtc *crtc;
  struct drm_framebuffer *fb;
  struct dma_fence *fence;
  int32_t crtc_x;//在crtc上的位置区域
  int32_t crtc_y;
  uint32_t crtc_w, crtc_h;
  uint32_t src_x;//图像可见的位置区域
  uint32_t src_y;
  uint32_t src_h, src_w;
  u16 alpha;
  uint16_t pixel_blend_mode;//混和方式
  unsigned int rotation;
  unsigned int zpos;        //平面在crtc上的优先级
  unsigned int normalized_zpos;
  enum drm_color_encoding color_encoding;
  enum drm_color_range color_range;
  struct drm_property_blob *fb_damage_clips;
  struct drm_rect src, dst;
  bool visible;
  enum drm_scaling_filter scaling_filter;
  struct drm_crtc_commit *commit;
  struct drm_atomic_state *state;
};

请注意,目标坐标crtc_xcrtc_ycrtc_h和 crtc_w以及源坐标src_xsrc_ysrc_hsrc_w是用户空间提供的原始坐标。驱动程序应该使用drm_atomic_helper_check_plane_state(),并且只使用src和dst中的派生矩形为硬件编程。

dumb buffer

KMS API 没有标准化支持存储对象的创建,而是将其留给特定于驱动程序的 ioctl。此外,即使对基于 GEM 的驱动程序,实际上创建缓冲区对象也是通过特定于驱动程序的 ioctl 完成的——GEM 只有一个通用的用户空间接口,用于共享和销毁对象。

dumb buffer通过提供标准 API 来创建适合扫描输出的dumb buffer部分缓解了该问题,然后可以使用该 API 创建 KMS 帧缓冲区。

为了支持dumb buffer,驱动程序必须实现drm_driver.dumb_create和drm_driver.dumb_map_offset。

在使用KMS驱动程序控制MIPI(Mobile Industry Processor Interface)显示屏时,需要编写特定的代码来初始化MIPI显示屏,并将其连接到KMS框架中。 以下是一些可能需要编写的代码片段: 1. MIPI显示屏初始化代码 MIPI显示屏通常需要进行初始化设置,以确保其与KMS驱动程序的兼容性。这些初始化设置可能包括分辨率、色彩模式、刷新率等。具体的初始化代码需要根据具体的MIPI显示屏型号和KMS驱动程序进行编写。 2. CRTC和encoder的配置代码 在将MIPI显示屏连接到KMS框架中之前,需要对CRTC和encoder进行配置。这些配置包括分辨率、色彩模式、刷新率等。可以使用KMS框架提供的API来配置CRTC和encoder。 3. 输出连接器(connector)的配置代码 在将MIPI显示屏连接到KMS框架中之前,需要配置输出连接器。输出连接器是KMS框架中的一个抽象层,用于将CRTC输出连接到显示设备。需要使用KMS框架提供的API来配置输出连接器。 4. 显示帧缓冲(framebuffer)的设置代码 在将MIPI显示屏连接到KMS框架中之前,需要设置显示帧缓冲。显示帧缓冲是一个用于存储图像数据的缓冲区,它包含了要在屏幕上显示的所有像素数据。需要使用KMS框架提供的API来设置显示帧缓冲。 需要注意的是,以上代码片段仅为示例代码,具体的实现方式可能因硬件和软件环境的不同而有所不同。在实际编写代码时,需要根据具体的硬件和软件环境进行相应的调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漫游嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值