[PATCH 2/7] drm/gma500: Move fbdev code into separate source file

Patrik Jakobsson patrik.r.jakobsson at gmail.com
Mon Feb 27 07:10:54 UTC 2023


On Thu, Feb 23, 2023 at 1:17 PM Thomas Zimmermann <tzimmermann at suse.de> wrote:
>
> Move the fbdev emulation from framebuffer.c into fbdev.c. Only build
> the source code if the Kconfig symbol has been selected. Remaining in
> framebuffer.c is gma500's code for DRM frambuffers. No functional
> hanges.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>

Hi Thomas, this patch doesn't apply to drm-misc. I seem to be missing
drm_fb_helper_prepare/unprepare().

-Patrik

> ---
>  drivers/gpu/drm/gma500/Makefile      |   1 +
>  drivers/gpu/drm/gma500/fbdev.c       | 325 +++++++++++++++++++++++++++
>  drivers/gpu/drm/gma500/framebuffer.c | 318 +-------------------------
>  drivers/gpu/drm/gma500/psb_drv.h     |  17 ++
>  4 files changed, 346 insertions(+), 315 deletions(-)
>  create mode 100644 drivers/gpu/drm/gma500/fbdev.c
>
> diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile
> index 63012bf2485a..4f302cd5e1a6 100644
> --- a/drivers/gpu/drm/gma500/Makefile
> +++ b/drivers/gpu/drm/gma500/Makefile
> @@ -38,5 +38,6 @@ gma500_gfx-y += \
>           psb_irq.o
>
>  gma500_gfx-$(CONFIG_ACPI) +=  opregion.o
> +gma500_gfx-$(CONFIG_DRM_FBDEV_EMULATION) +=  fbdev.o
>
>  obj-$(CONFIG_DRM_GMA500) += gma500_gfx.o
> diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
> new file mode 100644
> index 000000000000..9ce76b11d256
> --- /dev/null
> +++ b/drivers/gpu/drm/gma500/fbdev.c
> @@ -0,0 +1,325 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/**************************************************************************
> + * Copyright (c) 2007-2011, Intel Corporation.
> + * All Rights Reserved.
> + *
> + **************************************************************************/
> +
> +#include <linux/pfn_t.h>
> +
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_fb_helper.h>
> +#include <drm/drm_framebuffer.h>
> +
> +#include "gem.h"
> +#include "psb_drv.h"
> +
> +/*
> + * VM area struct
> + */
> +
> +static vm_fault_t psbfb_vm_fault(struct vm_fault *vmf)
> +{
> +       struct vm_area_struct *vma = vmf->vma;
> +       struct drm_framebuffer *fb = vma->vm_private_data;
> +       struct drm_device *dev = fb->dev;
> +       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> +       struct psb_gem_object *pobj = to_psb_gem_object(fb->obj[0]);
> +       int page_num;
> +       int i;
> +       unsigned long address;
> +       vm_fault_t ret = VM_FAULT_SIGBUS;
> +       unsigned long pfn;
> +       unsigned long phys_addr = (unsigned long)dev_priv->stolen_base + pobj->offset;
> +
> +       page_num = vma_pages(vma);
> +       address = vmf->address - (vmf->pgoff << PAGE_SHIFT);
> +
> +       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> +
> +       for (i = 0; i < page_num; i++) {
> +               pfn = (phys_addr >> PAGE_SHIFT);
> +
> +               ret = vmf_insert_mixed(vma, address, __pfn_to_pfn_t(pfn, PFN_DEV));
> +               if (unlikely(ret & VM_FAULT_ERROR))
> +                       break;
> +               address += PAGE_SIZE;
> +               phys_addr += PAGE_SIZE;
> +       }
> +       return ret;
> +}
> +
> +static void psbfb_vm_open(struct vm_area_struct *vma)
> +{ }
> +
> +static void psbfb_vm_close(struct vm_area_struct *vma)
> +{ }
> +
> +static const struct vm_operations_struct psbfb_vm_ops = {
> +       .fault  = psbfb_vm_fault,
> +       .open   = psbfb_vm_open,
> +       .close  = psbfb_vm_close
> +};
> +
> +/*
> + * struct fb_ops
> + */
> +
> +#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
> +
> +static int psbfb_setcolreg(unsigned int regno,
> +                          unsigned int red, unsigned int green,
> +                          unsigned int blue, unsigned int transp,
> +                          struct fb_info *info)
> +{
> +       struct drm_fb_helper *fb_helper = info->par;
> +       struct drm_framebuffer *fb = fb_helper->fb;
> +       uint32_t v;
> +
> +       if (!fb)
> +               return -ENOMEM;
> +
> +       if (regno > 255)
> +               return 1;
> +
> +       red = CMAP_TOHW(red, info->var.red.length);
> +       blue = CMAP_TOHW(blue, info->var.blue.length);
> +       green = CMAP_TOHW(green, info->var.green.length);
> +       transp = CMAP_TOHW(transp, info->var.transp.length);
> +
> +       v = (red << info->var.red.offset) |
> +           (green << info->var.green.offset) |
> +           (blue << info->var.blue.offset) |
> +           (transp << info->var.transp.offset);
> +
> +       if (regno < 16) {
> +               switch (fb->format->cpp[0] * 8) {
> +               case 16:
> +                       ((uint32_t *) info->pseudo_palette)[regno] = v;
> +                       break;
> +               case 24:
> +               case 32:
> +                       ((uint32_t *) info->pseudo_palette)[regno] = v;
> +                       break;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
> +{
> +       struct drm_fb_helper *fb_helper = info->par;
> +       struct drm_framebuffer *fb = fb_helper->fb;
> +
> +       if (vma->vm_pgoff != 0)
> +               return -EINVAL;
> +       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
> +               return -EINVAL;
> +
> +       /*
> +        * If this is a GEM object then info->screen_base is the virtual
> +        * kernel remapping of the object. FIXME: Review if this is
> +        * suitable for our mmap work
> +        */
> +       vma->vm_ops = &psbfb_vm_ops;
> +       vma->vm_private_data = (void *)fb;
> +       vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
> +
> +       return 0;
> +}
> +
> +static const struct fb_ops psbfb_unaccel_ops = {
> +       .owner = THIS_MODULE,
> +       DRM_FB_HELPER_DEFAULT_OPS,
> +       .fb_setcolreg = psbfb_setcolreg,
> +       .fb_read = drm_fb_helper_cfb_read,
> +       .fb_write = drm_fb_helper_cfb_write,
> +       .fb_fillrect = drm_fb_helper_cfb_fillrect,
> +       .fb_copyarea = drm_fb_helper_cfb_copyarea,
> +       .fb_imageblit = drm_fb_helper_cfb_imageblit,
> +       .fb_mmap = psbfb_mmap,
> +};
> +
> +/*
> + * struct drm_fb_helper_funcs
> + */
> +
> +static int psbfb_create(struct drm_fb_helper *fb_helper,
> +                       struct drm_fb_helper_surface_size *sizes)
> +{
> +       struct drm_device *dev = fb_helper->dev;
> +       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> +       struct pci_dev *pdev = to_pci_dev(dev->dev);
> +       struct fb_info *info;
> +       struct drm_framebuffer *fb;
> +       struct drm_mode_fb_cmd2 mode_cmd;
> +       int size;
> +       int ret;
> +       struct psb_gem_object *backing;
> +       struct drm_gem_object *obj;
> +       u32 bpp, depth;
> +
> +       mode_cmd.width = sizes->surface_width;
> +       mode_cmd.height = sizes->surface_height;
> +       bpp = sizes->surface_bpp;
> +       depth = sizes->surface_depth;
> +
> +       /* No 24bit packed */
> +       if (bpp == 24)
> +               bpp = 32;
> +
> +       mode_cmd.pitches[0] = ALIGN(mode_cmd.width * DIV_ROUND_UP(bpp, 8), 64);
> +
> +       size = mode_cmd.pitches[0] * mode_cmd.height;
> +       size = ALIGN(size, PAGE_SIZE);
> +
> +       /* Allocate the framebuffer in the GTT with stolen page backing */
> +       backing = psb_gem_create(dev, size, "fb", true, PAGE_SIZE);
> +       if (IS_ERR(backing))
> +               return PTR_ERR(backing);
> +       obj = &backing->base;
> +
> +       memset(dev_priv->vram_addr + backing->offset, 0, size);
> +
> +       info = drm_fb_helper_alloc_info(fb_helper);
> +       if (IS_ERR(info)) {
> +               ret = PTR_ERR(info);
> +               goto err_drm_gem_object_put;
> +       }
> +
> +       mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
> +
> +       fb = psb_framebuffer_create(dev, &mode_cmd, obj);
> +       if (IS_ERR(fb)) {
> +               ret = PTR_ERR(fb);
> +               goto err_drm_gem_object_put;
> +       }
> +
> +       fb_helper->fb = fb;
> +
> +       info->fbops = &psbfb_unaccel_ops;
> +
> +       info->fix.smem_start = dev_priv->fb_base;
> +       info->fix.smem_len = size;
> +       info->fix.ywrapstep = 0;
> +       info->fix.ypanstep = 0;
> +
> +       /* Accessed stolen memory directly */
> +       info->screen_base = dev_priv->vram_addr + backing->offset;
> +       info->screen_size = size;
> +
> +       drm_fb_helper_fill_info(info, fb_helper, sizes);
> +
> +       info->fix.mmio_start = pci_resource_start(pdev, 0);
> +       info->fix.mmio_len = pci_resource_len(pdev, 0);
> +
> +       /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
> +
> +       dev_dbg(dev->dev, "allocated %dx%d fb\n", fb->width, fb->height);
> +
> +       return 0;
> +
> +err_drm_gem_object_put:
> +       drm_gem_object_put(obj);
> +       return ret;
> +}
> +
> +static int psbfb_probe(struct drm_fb_helper *fb_helper,
> +                               struct drm_fb_helper_surface_size *sizes)
> +{
> +       struct drm_device *dev = fb_helper->dev;
> +       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> +       unsigned int fb_size;
> +       int bytespp;
> +
> +       bytespp = sizes->surface_bpp / 8;
> +       if (bytespp == 3)       /* no 24bit packed */
> +               bytespp = 4;
> +
> +       /*
> +        * If the mode will not fit in 32bit then switch to 16bit to get
> +        * a console on full resolution. The X mode setting server will
> +        * allocate its own 32bit GEM framebuffer
> +        */
> +       fb_size = ALIGN(sizes->surface_width * bytespp, 64) *
> +                 sizes->surface_height;
> +       fb_size = ALIGN(fb_size, PAGE_SIZE);
> +
> +       if (fb_size > dev_priv->vram_stolen_size) {
> +               sizes->surface_bpp = 16;
> +               sizes->surface_depth = 16;
> +       }
> +
> +       return psbfb_create(fb_helper, sizes);
> +}
> +
> +static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
> +       .fb_probe = psbfb_probe,
> +};
> +
> +static int psb_fbdev_destroy(struct drm_device *dev,
> +                            struct drm_fb_helper *fb_helper)
> +{
> +       struct drm_framebuffer *fb = fb_helper->fb;
> +
> +       drm_fb_helper_unregister_info(fb_helper);
> +
> +       drm_fb_helper_fini(fb_helper);
> +       drm_framebuffer_unregister_private(fb);
> +       drm_framebuffer_cleanup(fb);
> +
> +       if (fb->obj[0])
> +               drm_gem_object_put(fb->obj[0]);
> +       kfree(fb);
> +
> +       return 0;
> +}
> +
> +int psb_fbdev_init(struct drm_device *dev)
> +{
> +       struct drm_fb_helper *fb_helper;
> +       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> +       int ret;
> +
> +       fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
> +       if (!fb_helper)
> +               return -ENOMEM;
> +
> +       dev_priv->fb_helper = fb_helper;
> +
> +       drm_fb_helper_prepare(dev, fb_helper, 32, &psb_fb_helper_funcs);
> +
> +       ret = drm_fb_helper_init(dev, fb_helper);
> +       if (ret)
> +               goto free;
> +
> +       /* disable all the possible outputs/crtcs before entering KMS mode */
> +       drm_helper_disable_unused_functions(dev);
> +
> +       ret = drm_fb_helper_initial_config(fb_helper);
> +       if (ret)
> +               goto fini;
> +
> +       return 0;
> +
> +fini:
> +       drm_fb_helper_fini(fb_helper);
> +free:
> +       drm_fb_helper_unprepare(fb_helper);
> +       kfree(fb_helper);
> +       return ret;
> +}
> +
> +void psb_fbdev_fini(struct drm_device *dev)
> +{
> +       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> +
> +       if (!dev_priv->fb_helper)
> +               return;
> +
> +       psb_fbdev_destroy(dev, dev_priv->fb_helper);
> +       drm_fb_helper_unprepare(dev_priv->fb_helper);
> +       kfree(dev_priv->fb_helper);
> +       dev_priv->fb_helper = NULL;
> +}
> diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
> index df4dbc509f68..506b881a7b24 100644
> --- a/drivers/gpu/drm/gma500/framebuffer.c
> +++ b/drivers/gpu/drm/gma500/framebuffer.c
> @@ -5,16 +5,12 @@
>   *
>   **************************************************************************/
>
> -#include <linux/pfn_t.h>
> -
> -#include <drm/drm_crtc_helper.h>
>  #include <drm/drm_fb_helper.h>
>  #include <drm/drm_framebuffer.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_modeset_helper.h>
>
>  #include "framebuffer.h"
> -#include "gem.h"
>  #include "psb_drv.h"
>
>  static const struct drm_framebuffer_funcs psb_fb_funcs = {
> @@ -22,126 +18,6 @@ static const struct drm_framebuffer_funcs psb_fb_funcs = {
>         .create_handle = drm_gem_fb_create_handle,
>  };
>
> -#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
> -
> -static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
> -                          unsigned blue, unsigned transp,
> -                          struct fb_info *info)
> -{
> -       struct drm_fb_helper *fb_helper = info->par;
> -       struct drm_framebuffer *fb = fb_helper->fb;
> -       uint32_t v;
> -
> -       if (!fb)
> -               return -ENOMEM;
> -
> -       if (regno > 255)
> -               return 1;
> -
> -       red = CMAP_TOHW(red, info->var.red.length);
> -       blue = CMAP_TOHW(blue, info->var.blue.length);
> -       green = CMAP_TOHW(green, info->var.green.length);
> -       transp = CMAP_TOHW(transp, info->var.transp.length);
> -
> -       v = (red << info->var.red.offset) |
> -           (green << info->var.green.offset) |
> -           (blue << info->var.blue.offset) |
> -           (transp << info->var.transp.offset);
> -
> -       if (regno < 16) {
> -               switch (fb->format->cpp[0] * 8) {
> -               case 16:
> -                       ((uint32_t *) info->pseudo_palette)[regno] = v;
> -                       break;
> -               case 24:
> -               case 32:
> -                       ((uint32_t *) info->pseudo_palette)[regno] = v;
> -                       break;
> -               }
> -       }
> -
> -       return 0;
> -}
> -
> -static vm_fault_t psbfb_vm_fault(struct vm_fault *vmf)
> -{
> -       struct vm_area_struct *vma = vmf->vma;
> -       struct drm_framebuffer *fb = vma->vm_private_data;
> -       struct drm_device *dev = fb->dev;
> -       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> -       struct psb_gem_object *pobj = to_psb_gem_object(fb->obj[0]);
> -       int page_num;
> -       int i;
> -       unsigned long address;
> -       vm_fault_t ret = VM_FAULT_SIGBUS;
> -       unsigned long pfn;
> -       unsigned long phys_addr = (unsigned long)dev_priv->stolen_base + pobj->offset;
> -
> -       page_num = vma_pages(vma);
> -       address = vmf->address - (vmf->pgoff << PAGE_SHIFT);
> -
> -       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> -
> -       for (i = 0; i < page_num; i++) {
> -               pfn = (phys_addr >> PAGE_SHIFT);
> -
> -               ret = vmf_insert_mixed(vma, address,
> -                               __pfn_to_pfn_t(pfn, PFN_DEV));
> -               if (unlikely(ret & VM_FAULT_ERROR))
> -                       break;
> -               address += PAGE_SIZE;
> -               phys_addr += PAGE_SIZE;
> -       }
> -       return ret;
> -}
> -
> -static void psbfb_vm_open(struct vm_area_struct *vma)
> -{
> -}
> -
> -static void psbfb_vm_close(struct vm_area_struct *vma)
> -{
> -}
> -
> -static const struct vm_operations_struct psbfb_vm_ops = {
> -       .fault  = psbfb_vm_fault,
> -       .open   = psbfb_vm_open,
> -       .close  = psbfb_vm_close
> -};
> -
> -static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
> -{
> -       struct drm_fb_helper *fb_helper = info->par;
> -       struct drm_framebuffer *fb = fb_helper->fb;
> -
> -       if (vma->vm_pgoff != 0)
> -               return -EINVAL;
> -       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
> -               return -EINVAL;
> -
> -       /*
> -        * If this is a GEM object then info->screen_base is the virtual
> -        * kernel remapping of the object. FIXME: Review if this is
> -        * suitable for our mmap work
> -        */
> -       vma->vm_ops = &psbfb_vm_ops;
> -       vma->vm_private_data = (void *)fb;
> -       vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
> -       return 0;
> -}
> -
> -static const struct fb_ops psbfb_unaccel_ops = {
> -       .owner = THIS_MODULE,
> -       DRM_FB_HELPER_DEFAULT_OPS,
> -       .fb_setcolreg = psbfb_setcolreg,
> -       .fb_read = drm_fb_helper_cfb_read,
> -       .fb_write = drm_fb_helper_cfb_write,
> -       .fb_fillrect = drm_fb_helper_cfb_fillrect,
> -       .fb_copyarea = drm_fb_helper_cfb_copyarea,
> -       .fb_imageblit = drm_fb_helper_cfb_imageblit,
> -       .fb_mmap = psbfb_mmap,
> -};
> -
>  /**
>   *     psb_framebuffer_init    -       initialize a framebuffer
>   *     @dev: our DRM device
> @@ -192,11 +68,9 @@ static int psb_framebuffer_init(struct drm_device *dev,
>   *
>   *     TODO: review object references
>   */
> -
> -static struct drm_framebuffer *psb_framebuffer_create
> -                       (struct drm_device *dev,
> -                        const struct drm_mode_fb_cmd2 *mode_cmd,
> -                        struct drm_gem_object *obj)
> +struct drm_framebuffer *psb_framebuffer_create(struct drm_device *dev,
> +                                              const struct drm_mode_fb_cmd2 *mode_cmd,
> +                                              struct drm_gem_object *obj)
>  {
>         struct drm_framebuffer *fb;
>         int ret;
> @@ -213,93 +87,6 @@ static struct drm_framebuffer *psb_framebuffer_create
>         return fb;
>  }
>
> -/**
> - *     psbfb_create            -       create a framebuffer
> - *     @fb_helper: the framebuffer helper
> - *     @sizes: specification of the layout
> - *
> - *     Create a framebuffer to the specifications provided
> - */
> -static int psbfb_create(struct drm_fb_helper *fb_helper,
> -                               struct drm_fb_helper_surface_size *sizes)
> -{
> -       struct drm_device *dev = fb_helper->dev;
> -       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> -       struct pci_dev *pdev = to_pci_dev(dev->dev);
> -       struct fb_info *info;
> -       struct drm_framebuffer *fb;
> -       struct drm_mode_fb_cmd2 mode_cmd;
> -       int size;
> -       int ret;
> -       struct psb_gem_object *backing;
> -       struct drm_gem_object *obj;
> -       u32 bpp, depth;
> -
> -       mode_cmd.width = sizes->surface_width;
> -       mode_cmd.height = sizes->surface_height;
> -       bpp = sizes->surface_bpp;
> -       depth = sizes->surface_depth;
> -
> -       /* No 24bit packed */
> -       if (bpp == 24)
> -               bpp = 32;
> -
> -       mode_cmd.pitches[0] = ALIGN(mode_cmd.width * DIV_ROUND_UP(bpp, 8), 64);
> -
> -       size = mode_cmd.pitches[0] * mode_cmd.height;
> -       size = ALIGN(size, PAGE_SIZE);
> -
> -       /* Allocate the framebuffer in the GTT with stolen page backing */
> -       backing = psb_gem_create(dev, size, "fb", true, PAGE_SIZE);
> -       if (IS_ERR(backing))
> -               return PTR_ERR(backing);
> -       obj = &backing->base;
> -
> -       memset(dev_priv->vram_addr + backing->offset, 0, size);
> -
> -       info = drm_fb_helper_alloc_info(fb_helper);
> -       if (IS_ERR(info)) {
> -               ret = PTR_ERR(info);
> -               goto err_drm_gem_object_put;
> -       }
> -
> -       mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
> -
> -       fb = psb_framebuffer_create(dev, &mode_cmd, obj);
> -       if (IS_ERR(fb)) {
> -               ret = PTR_ERR(fb);
> -               goto err_drm_gem_object_put;
> -       }
> -
> -       fb_helper->fb = fb;
> -
> -       info->fbops = &psbfb_unaccel_ops;
> -
> -       info->fix.smem_start = dev_priv->fb_base;
> -       info->fix.smem_len = size;
> -       info->fix.ywrapstep = 0;
> -       info->fix.ypanstep = 0;
> -
> -       /* Accessed stolen memory directly */
> -       info->screen_base = dev_priv->vram_addr + backing->offset;
> -       info->screen_size = size;
> -
> -       drm_fb_helper_fill_info(info, fb_helper, sizes);
> -
> -       info->fix.mmio_start = pci_resource_start(pdev, 0);
> -       info->fix.mmio_len = pci_resource_len(pdev, 0);
> -
> -       /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
> -
> -       dev_dbg(dev->dev, "allocated %dx%d fb\n", fb->width, fb->height);
> -
> -       return 0;
> -
> -err_drm_gem_object_put:
> -       drm_gem_object_put(obj);
> -       return ret;
> -}
> -
>  /**
>   *     psb_user_framebuffer_create     -       create framebuffer
>   *     @dev: our DRM device
> @@ -331,105 +118,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create
>         return fb;
>  }
>
> -static int psbfb_probe(struct drm_fb_helper *fb_helper,
> -                               struct drm_fb_helper_surface_size *sizes)
> -{
> -       struct drm_device *dev = fb_helper->dev;
> -       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> -       unsigned int fb_size;
> -       int bytespp;
> -
> -       bytespp = sizes->surface_bpp / 8;
> -       if (bytespp == 3)       /* no 24bit packed */
> -               bytespp = 4;
> -
> -       /* If the mode will not fit in 32bit then switch to 16bit to get
> -          a console on full resolution. The X mode setting server will
> -          allocate its own 32bit GEM framebuffer */
> -       fb_size = ALIGN(sizes->surface_width * bytespp, 64) *
> -                 sizes->surface_height;
> -       fb_size = ALIGN(fb_size, PAGE_SIZE);
> -
> -       if (fb_size > dev_priv->vram_stolen_size) {
> -                sizes->surface_bpp = 16;
> -                sizes->surface_depth = 16;
> -        }
> -
> -       return psbfb_create(fb_helper, sizes);
> -}
> -
> -static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
> -       .fb_probe = psbfb_probe,
> -};
> -
> -static int psb_fbdev_destroy(struct drm_device *dev,
> -                            struct drm_fb_helper *fb_helper)
> -{
> -       struct drm_framebuffer *fb = fb_helper->fb;
> -
> -       drm_fb_helper_unregister_info(fb_helper);
> -
> -       drm_fb_helper_fini(fb_helper);
> -       drm_framebuffer_unregister_private(fb);
> -       drm_framebuffer_cleanup(fb);
> -
> -       if (fb->obj[0])
> -               drm_gem_object_put(fb->obj[0]);
> -       kfree(fb);
> -
> -       return 0;
> -}
> -
> -int psb_fbdev_init(struct drm_device *dev)
> -{
> -       struct drm_fb_helper *fb_helper;
> -       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> -       int ret;
> -
> -       fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
> -       if (!fb_helper) {
> -               dev_err(dev->dev, "no memory\n");
> -               return -ENOMEM;
> -       }
> -
> -       dev_priv->fb_helper = fb_helper;
> -
> -       drm_fb_helper_prepare(dev, fb_helper, 32, &psb_fb_helper_funcs);
> -
> -       ret = drm_fb_helper_init(dev, fb_helper);
> -       if (ret)
> -               goto free;
> -
> -       /* disable all the possible outputs/crtcs before entering KMS mode */
> -       drm_helper_disable_unused_functions(dev);
> -
> -       ret = drm_fb_helper_initial_config(fb_helper);
> -       if (ret)
> -               goto fini;
> -
> -       return 0;
> -
> -fini:
> -       drm_fb_helper_fini(fb_helper);
> -free:
> -       drm_fb_helper_unprepare(fb_helper);
> -       kfree(fb_helper);
> -       return ret;
> -}
> -
> -static void psb_fbdev_fini(struct drm_device *dev)
> -{
> -       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
> -
> -       if (!dev_priv->fb_helper)
> -               return;
> -
> -       psb_fbdev_destroy(dev, dev_priv->fb_helper);
> -       drm_fb_helper_unprepare(dev_priv->fb_helper);
> -       kfree(dev_priv->fb_helper);
> -       dev_priv->fb_helper = NULL;
> -}
> -
>  static const struct drm_mode_config_funcs psb_mode_funcs = {
>         .fb_create = psb_user_framebuffer_create,
>         .output_poll_changed = drm_fb_helper_output_poll_changed,
> diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
> index a5df6d2f2cab..cd0a30011572 100644
> --- a/drivers/gpu/drm/gma500/psb_drv.h
> +++ b/drivers/gpu/drm/gma500/psb_drv.h
> @@ -610,7 +610,24 @@ extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv);
>  /* modesetting */
>  extern void psb_modeset_init(struct drm_device *dev);
>  extern void psb_modeset_cleanup(struct drm_device *dev);
> +
> +/* framebuffer */
> +extern struct drm_framebuffer *psb_framebuffer_create(struct drm_device *dev,
> +                                                     const struct drm_mode_fb_cmd2 *mode_cmd,
> +                                                     struct drm_gem_object *obj);
> +
> +/* fbdev */
> +#if defined(CONFIG_DRM_FBDEV_EMULATION)
>  extern int psb_fbdev_init(struct drm_device *dev);
> +extern void psb_fbdev_fini(struct drm_device *dev);
> +#else
> +int psb_fbdev_init(struct drm_device *dev)
> +{
> +       return 0;
> +}
> +void psb_fbdev_fini(struct drm_device *dev)
> +{ }
> +#endif
>
>  /* backlight.c */
>  int gma_backlight_init(struct drm_device *dev);
> --
> 2.39.2
>


More information about the dri-devel mailing list