转自:https://blog.csdn.net/jingxia2008/article/details/48804859

drm 驱动是如何创建 fb device 的drm 驱动是如何创建 fb device 的什么是 drm如何使用 drm 接口libdrmfb device本文讨论的问题是 drm 驱动是如何虚拟 drm crts 为 fb device设备驱动创建 fbdev完成 fb 设备的创建流程图什么是 drm?drm 是一个 Linux 内核的显示系统驱动框架,区别于另外一个 DRM数字版权保护

drm 是一个管理 GPU 的显示框架在内核级别提供内存管理,中断处理, DMA控为应用程序提供统一的操作接口如何使用 drm 接口libdrmfb devicelibdrm内核提供的 IOCTRL 太多,libdrm 用于简化编程管理当前的显示器,并修改当前的模式成为 KMS ( drm-kms - Kernel Mode-Setting)

借助 libdrm 的强大 API 接口,如果内核支持 PRIME API ,也可以使用 PRIME 接口实现更为灵活的内存操作。

fb devicedrm 驱动可以模拟一个 fb device, 默认是 default CRTC, 更多关于 fb device ,可以参考 内核 framebuffer 文档, fb device 是大多数 Linux 系统显示的基础。

The X Server, Linux 桌面系统的显示服务Android gralloc, 安卓系统显示 HAL本文讨论的问题是 drm 驱动是如何虚拟 drm crts 为 fb device文章基于内核版本 linux-3.18

VERSION = 3PATCHLEVEL = 18SUBLEVEL = 0EXTRAVERSION = -linux4sam_5.0-alpha7NAME = Diseased Newt12345drm 的代码位于:

drivers/gpu/drm/11. 设备驱动创建 fbdevdrivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c: dc->fbdev = drm_fbdev_cma_init(dev, 24, drivers/gpu/drm/sti/sti_drm_drv.c: drm_fbdev_cma_init(dev, 32, drivers/gpu/drm/tilcdc/tilcdc_drv.c: priv->fbdev = drm_fbdev_cma_init(dev, bpp, drivers/gpu/drm/rcar-du/rcar_du_kms.c: fbdev = drm_fbdev_cma_init(dev, 32, dev->mode_config.num_crtc,

调用的是 drm_fbdev_cma_init

struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,unsigned int preferred_bpp, unsigned int num_crtc,unsigned int max_conn_count){struct drm_fbdev_cma *fbdev_cma;struct drm_fb_helper *helper;int ret;

fbdev_cma = kzalloc(sizeof(*fbdev_cma), GFP_KERNEL);

...helper = &fbdev_cma->fb_helper;

drm_fb_helper_prepare(dev, helper, &drm_fb_cma_helper_funcs);

...ret = drm_fb_helper_initial_config(helper, preferred_bpp); if (ret < 0) { dev_err(dev->dev, "Failed to set initial hw configuration.\n"); goto err_drm_fb_helper_fini;}

return fbdev_cma;其中最重要的数据结构是 drm_fb_helper_funcs

static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = {.fb_probe = drm_fbdev_cma_create,12};

2. 完成 fb 设备的创建:static int drm_fbdev_cma_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes){ struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper); struct drm_mode_fb_cmd2 mode_cmd = { 0 }; struct drm_device *dev = helper->dev; struct drm_gem_cma_object *obj; struct drm_framebuffer *fb; unsigned int bytes_per_pixel; unsigned long offset; struct fb_info *fbi; size_t size; int ret;

DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n", sizes->surface_width, sizes->surface_height, sizes->surface_bpp);

bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8);

mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; mode_cmd.pitches[0] = sizes->surface_width * bytes_per_pixel; mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);

size = mode_cmd.pitches[0] * mode_cmd.height; obj = drm_gem_cma_create(dev, size); if (IS_ERR(obj)) return -ENOMEM;

fbi = framebuffer_alloc(0, dev->dev); if (!fbi) { dev_err(dev->dev, "Failed to allocate framebuffer info.\n"); ret = -ENOMEM; goto err_drm_gem_cma_free_object; }

fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1); if (IS_ERR(fbdev_cma->fb)) { dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); ret = PTR_ERR(fbdev_cma->fb); goto err_framebuffer_release; }

fb = &fbdev_cma->fb->fb; helper->fb = fb; helper->fbdev = fbi;

fbi->par = helper; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->fbops = &drm_fbdev_cma_ops;

ret = fb_alloc_cmap(&fbi->cmap, 256, 0); if (ret) { dev_err(dev->dev, "Failed to allocate color map.\n"); goto err_drm_fb_cma_destroy; }

drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);

offset = fbi->var.xoffset * bytes_per_pixel; offset += fbi->var.yoffset * fb->pitches[0];

dev->mode_config.fb_base = (resource_size_t)obj->paddr; fbi->screen_base = obj->vaddr + offset; fbi->fix.smem_start = (unsigned long)(obj->paddr + offset); fbi->screen_size = size; fbi->fix.smem_len = size;

return 0;

err_drm_fb_cma_destroy: drm_framebuffer_unregister_private(fb); drm_fb_cma_destroy(fb);err_framebuffer_release: framebuffer_release(fbi);err_drm_gem_cma_free_object: drm_gem_cma_free_object(&obj->base); return ret;}1流程图drm_fbdev_cma_initdrm_fb_helper_initial_configdrm_fb_helper_single_fb_proberegister_framebuffer————————————————版权声明:本文为CSDN博主「无才顽石」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/jingxia2008/article/details/48804859

好文链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。