struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, struct drm_device *drm, unsigned int size, unsigned long flags, unsigned int *handle) { struct tegra_bo *bo; int ret; bo = tegra_bo_create(drm, size, flags); if (IS_ERR(bo)) return bo; ret = drm_gem_handle_create(file, &bo->gem, handle); if (ret) goto err; drm_gem_object_unreference_unlocked(&bo->gem); return bo; err: tegra_bo_free_object(&bo->gem); return ERR_PTR(ret); }
struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, struct drm_device *drm, size_t size, unsigned long flags, u32 *handle) { struct tegra_bo *bo; int err; bo = tegra_bo_create(drm, size, flags); if (IS_ERR(bo)) return bo; err = drm_gem_handle_create(file, &bo->gem, handle); if (err) { tegra_bo_free_object(&bo->gem); return ERR_PTR(err); } drm_gem_object_unreference_unlocked(&bo->gem); return bo; }
static int tegra_fbdev_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { struct tegra_fbdev *fbdev = to_tegra_fbdev(helper); struct tegra_drm *tegra = helper->dev->dev_private; struct drm_device *drm = helper->dev; struct drm_mode_fb_cmd2 cmd = { 0 }; unsigned int bytes_per_pixel; struct drm_framebuffer *fb; unsigned long offset; struct fb_info *info; struct tegra_bo *bo; size_t size; int err; bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); cmd.width = sizes->surface_width; cmd.height = sizes->surface_height; cmd.pitches[0] = round_up(sizes->surface_width * bytes_per_pixel, tegra->pitch_align); cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); size = cmd.pitches[0] * cmd.height; bo = tegra_bo_create(drm, size, 0); if (IS_ERR(bo)) return PTR_ERR(bo); info = framebuffer_alloc(0, drm->dev); if (!info) { dev_err(drm->dev, "failed to allocate framebuffer info\n"); tegra_bo_free_object(&bo->gem); return -ENOMEM; } fbdev->fb = tegra_fb_alloc(drm, &cmd, &bo, 1); if (IS_ERR(fbdev->fb)) { dev_err(drm->dev, "failed to allocate DRM framebuffer\n"); err = PTR_ERR(fbdev->fb); goto release; } fb = &fbdev->fb->base; helper->fb = fb; helper->fbdev = info; info->par = helper; info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &tegra_fb_ops; err = fb_alloc_cmap(&info->cmap, 256, 0); if (err < 0) { dev_err(drm->dev, "failed to allocate color map: %d\n", err); goto destroy; } drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, helper, fb->width, fb->height); offset = info->var.xoffset * bytes_per_pixel + info->var.yoffset * fb->pitches[0]; drm->mode_config.fb_base = (resource_size_t)bo->paddr; info->screen_base = (void __iomem *)bo->vaddr + offset; info->screen_size = size; info->fix.smem_start = (unsigned long)(bo->paddr + offset); info->fix.smem_len = size; return 0; destroy: drm_framebuffer_unregister_private(fb); tegra_fb_destroy(fb); release: framebuffer_release(info); return err; }