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

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


On Mon, Feb 27, 2023 at 8:41 AM Thomas Zimmermann <tzimmermann at suse.de> wrote:
>
> Hi
>
> Am 27.02.23 um 08:10 schrieb Patrik Jakobsson:
> > 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().
>
> Could be. I'm on drm-tip for development. And we're in the merge window,
> which is a bad time to sync-ing trees. Let me see if I can easiyl
> backmerge now. Or otherwise things should stabilize after -rc1 has been
> tagged.

No worries, I'll just review this against drm-tip instead.

>
> Best regards
> Thomas
>
> >
> > -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
> >>
>
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Ivo Totev


More information about the dri-devel mailing list