diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/gpu/drm/tegra/fb.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/gpu/drm/tegra/fb.c')
| -rw-r--r-- | drivers/gpu/drm/tegra/fb.c | 242 | 
1 files changed, 4 insertions, 238 deletions
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index bfebe2786d61..a719af1dc9a5 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -17,13 +17,6 @@  #include "drm.h"  #include "gem.h" -#ifdef CONFIG_DRM_FBDEV_EMULATION -static inline struct tegra_fbdev *to_tegra_fbdev(struct drm_fb_helper *helper) -{ -	return container_of(helper, struct tegra_fbdev, base); -} -#endif -  struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,  				    unsigned int index)  { @@ -108,10 +101,10 @@ static const struct drm_framebuffer_funcs tegra_fb_funcs = {  	.create_handle = drm_gem_fb_create_handle,  }; -static struct drm_framebuffer *tegra_fb_alloc(struct drm_device *drm, -					      const struct drm_mode_fb_cmd2 *mode_cmd, -					      struct tegra_bo **planes, -					      unsigned int num_planes) +struct drm_framebuffer *tegra_fb_alloc(struct drm_device *drm, +				       const struct drm_mode_fb_cmd2 *mode_cmd, +				       struct tegra_bo **planes, +				       unsigned int num_planes)  {  	struct drm_framebuffer *fb;  	unsigned int i; @@ -186,230 +179,3 @@ unreference:  	return ERR_PTR(err);  } - -#ifdef CONFIG_DRM_FBDEV_EMULATION -static int tegra_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ -	struct drm_fb_helper *helper = info->par; -	struct tegra_bo *bo; -	int err; - -	bo = tegra_fb_get_plane(helper->fb, 0); - -	err = drm_gem_mmap_obj(&bo->gem, bo->gem.size, vma); -	if (err < 0) -		return err; - -	return __tegra_gem_mmap(&bo->gem, vma); -} - -static const struct fb_ops tegra_fb_ops = { -	.owner = THIS_MODULE, -	DRM_FB_HELPER_DEFAULT_OPS, -	.fb_read = drm_fb_helper_sys_read, -	.fb_write = drm_fb_helper_sys_write, -	.fb_fillrect = drm_fb_helper_sys_fillrect, -	.fb_copyarea = drm_fb_helper_sys_copyarea, -	.fb_imageblit = drm_fb_helper_sys_imageblit, -	.fb_mmap = tegra_fb_mmap, -}; - -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 = drm_fb_helper_alloc_info(helper); -	if (IS_ERR(info)) { -		dev_err(drm->dev, "failed to allocate framebuffer info\n"); -		drm_gem_object_put(&bo->gem); -		return PTR_ERR(info); -	} - -	fbdev->fb = tegra_fb_alloc(drm, &cmd, &bo, 1); -	if (IS_ERR(fbdev->fb)) { -		err = PTR_ERR(fbdev->fb); -		dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n", -			err); -		drm_gem_object_put(&bo->gem); -		return PTR_ERR(fbdev->fb); -	} - -	fb = fbdev->fb; -	helper->fb = fb; -	helper->info = info; - -	info->fbops = &tegra_fb_ops; - -	drm_fb_helper_fill_info(info, helper, sizes); - -	offset = info->var.xoffset * bytes_per_pixel + -		 info->var.yoffset * fb->pitches[0]; - -	if (bo->pages) { -		bo->vaddr = vmap(bo->pages, bo->num_pages, VM_MAP, -				 pgprot_writecombine(PAGE_KERNEL)); -		if (!bo->vaddr) { -			dev_err(drm->dev, "failed to vmap() framebuffer\n"); -			err = -ENOMEM; -			goto destroy; -		} -	} - -	info->screen_base = (void __iomem *)bo->vaddr + offset; -	info->screen_size = size; -	info->fix.smem_start = (unsigned long)(bo->iova + offset); -	info->fix.smem_len = size; - -	return 0; - -destroy: -	drm_framebuffer_remove(fb); -	return err; -} - -static const struct drm_fb_helper_funcs tegra_fb_helper_funcs = { -	.fb_probe = tegra_fbdev_probe, -}; - -static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm) -{ -	struct tegra_fbdev *fbdev; - -	fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); -	if (!fbdev) { -		dev_err(drm->dev, "failed to allocate DRM fbdev\n"); -		return ERR_PTR(-ENOMEM); -	} - -	drm_fb_helper_prepare(drm, &fbdev->base, 32, &tegra_fb_helper_funcs); - -	return fbdev; -} - -static void tegra_fbdev_free(struct tegra_fbdev *fbdev) -{ -	drm_fb_helper_unprepare(&fbdev->base); -	kfree(fbdev); -} - -static int tegra_fbdev_init(struct tegra_fbdev *fbdev, -			    unsigned int num_crtc, -			    unsigned int max_connectors) -{ -	struct drm_device *drm = fbdev->base.dev; -	int err; - -	err = drm_fb_helper_init(drm, &fbdev->base); -	if (err < 0) { -		dev_err(drm->dev, "failed to initialize DRM FB helper: %d\n", -			err); -		return err; -	} - -	err = drm_fb_helper_initial_config(&fbdev->base); -	if (err < 0) { -		dev_err(drm->dev, "failed to set initial configuration: %d\n", -			err); -		goto fini; -	} - -	return 0; - -fini: -	drm_fb_helper_fini(&fbdev->base); -	return err; -} - -static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) -{ -	drm_fb_helper_unregister_info(&fbdev->base); - -	if (fbdev->fb) { -		struct tegra_bo *bo = tegra_fb_get_plane(fbdev->fb, 0); - -		/* Undo the special mapping we made in fbdev probe. */ -		if (bo && bo->pages) { -			vunmap(bo->vaddr); -			bo->vaddr = NULL; -		} - -		drm_framebuffer_remove(fbdev->fb); -	} - -	drm_fb_helper_fini(&fbdev->base); -	tegra_fbdev_free(fbdev); -} -#endif - -int tegra_drm_fb_prepare(struct drm_device *drm) -{ -#ifdef CONFIG_DRM_FBDEV_EMULATION -	struct tegra_drm *tegra = drm->dev_private; - -	tegra->fbdev = tegra_fbdev_create(drm); -	if (IS_ERR(tegra->fbdev)) -		return PTR_ERR(tegra->fbdev); -#endif - -	return 0; -} - -void tegra_drm_fb_free(struct drm_device *drm) -{ -#ifdef CONFIG_DRM_FBDEV_EMULATION -	struct tegra_drm *tegra = drm->dev_private; - -	tegra_fbdev_free(tegra->fbdev); -#endif -} - -int tegra_drm_fb_init(struct drm_device *drm) -{ -#ifdef CONFIG_DRM_FBDEV_EMULATION -	struct tegra_drm *tegra = drm->dev_private; -	int err; - -	err = tegra_fbdev_init(tegra->fbdev, drm->mode_config.num_crtc, -			       drm->mode_config.num_connector); -	if (err < 0) -		return err; -#endif - -	return 0; -} - -void tegra_drm_fb_exit(struct drm_device *drm) -{ -#ifdef CONFIG_DRM_FBDEV_EMULATION -	struct tegra_drm *tegra = drm->dev_private; - -	tegra_fbdev_exit(tegra->fbdev); -#endif -}  |