diff options
author | Maxime Ripard <maxime@cerno.tech> | 2023-05-12 10:47:12 +0300 |
---|---|---|
committer | Maxime Ripard <maxime@cerno.tech> | 2023-05-12 10:47:12 +0300 |
commit | 50282fd57bcd3525c9d81eef58df8718e4337c6d (patch) | |
tree | 9795dfdb1a9b66904d9320f33c9216683d10576a /drivers/gpu/drm/gma500 | |
parent | ad81e23426a651eb89a4b306e1c4169e6308c124 (diff) | |
parent | ac9a78681b921877518763ba0e89202254349d1b (diff) | |
download | linux-50282fd57bcd3525c9d81eef58df8718e4337c6d.tar.xz |
Merge drm/drm-fixes into drm-misc-fixes
Let's bring 6.4-rc1 in drm-misc-fixes to start the new fix cycle.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r-- | drivers/gpu/drm/gma500/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/fbdev.c | 344 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/framebuffer.c | 341 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_drv.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_drv.h | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_irq.c | 11 |
6 files changed, 363 insertions, 358 deletions
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..62287407e717 --- /dev/null +++ b/drivers/gpu/drm/gma500/fbdev.c @@ -0,0 +1,344 @@ +// 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_drv.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 psb_fbdev_vm_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + struct fb_info *info = vma->vm_private_data; + unsigned long address = vmf->address - (vmf->pgoff << PAGE_SHIFT); + unsigned long pfn = info->fix.smem_start >> PAGE_SHIFT; + vm_fault_t err = VM_FAULT_SIGBUS; + unsigned long page_num = vma_pages(vma); + unsigned long i; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + for (i = 0; i < page_num; ++i) { + err = vmf_insert_mixed(vma, address, __pfn_to_pfn_t(pfn, PFN_DEV)); + if (unlikely(err & VM_FAULT_ERROR)) + break; + address += PAGE_SIZE; + ++pfn; + } + + return err; +} + +static const struct vm_operations_struct psb_fbdev_vm_ops = { + .fault = psb_fbdev_vm_fault, +}; + +/* + * struct fb_ops + */ + +#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) + +static int psb_fbdev_fb_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 psb_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + 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 = &psb_fbdev_vm_ops; + vma->vm_private_data = info; + vm_flags_set(vma, VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP); + + return 0; +} + +static void psb_fbdev_fb_destroy(struct fb_info *info) +{ + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_gem_object *obj = fb->obj[0]; + + drm_fb_helper_fini(fb_helper); + + drm_framebuffer_unregister_private(fb); + fb->obj[0] = NULL; + drm_framebuffer_cleanup(fb); + kfree(fb); + + drm_gem_object_put(obj); + + drm_client_release(&fb_helper->client); + + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); +} + +static const struct fb_ops psb_fbdev_fb_ops = { + .owner = THIS_MODULE, + DRM_FB_HELPER_DEFAULT_OPS, + .fb_setcolreg = psb_fbdev_fb_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 = psb_fbdev_fb_mmap, + .fb_destroy = psb_fbdev_fb_destroy, +}; + +/* + * struct drm_fb_helper_funcs + */ + +static int psb_fbdev_fb_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); + 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; + + /* No 24-bit packed mode */ + if (sizes->surface_bpp == 24) { + sizes->surface_bpp = 32; + sizes->surface_depth = 24; + } + bpp = sizes->surface_bpp; + depth = sizes->surface_depth; + + /* + * If the mode does not fit in 32 bit then switch to 16 bit to get + * a console on full resolution. The X mode setting server will + * allocate its own 32-bit GEM framebuffer. + */ + size = ALIGN(sizes->surface_width * DIV_ROUND_UP(bpp, 8), 64) * + sizes->surface_height; + size = ALIGN(size, PAGE_SIZE); + + if (size > dev_priv->vram_stolen_size) { + sizes->surface_bpp = 16; + sizes->surface_depth = 16; + } + bpp = sizes->surface_bpp; + depth = sizes->surface_depth; + + mode_cmd.width = sizes->surface_width; + mode_cmd.height = sizes->surface_height; + mode_cmd.pitches[0] = ALIGN(mode_cmd.width * DIV_ROUND_UP(bpp, 8), 64); + mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); + + 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; + + 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 = drm_fb_helper_alloc_info(fb_helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); + goto err_drm_framebuffer_unregister_private; + } + + info->fbops = &psb_fbdev_fb_ops; + info->flags = FBINFO_DEFAULT; + /* 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.smem_start = dev_priv->stolen_base + backing->offset; + info->fix.smem_len = size; + info->fix.ywrapstep = 0; + info->fix.ypanstep = 0; + info->fix.mmio_start = pci_resource_start(pdev, 0); + info->fix.mmio_len = pci_resource_len(pdev, 0); + + memset(info->screen_base, 0, info->screen_size); + + /* 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_framebuffer_unregister_private: + drm_framebuffer_unregister_private(fb); + fb->obj[0] = NULL; + drm_framebuffer_cleanup(fb); + kfree(fb); +err_drm_gem_object_put: + drm_gem_object_put(obj); + return ret; +} + +static const struct drm_fb_helper_funcs psb_fbdev_fb_helper_funcs = { + .fb_probe = psb_fbdev_fb_probe, +}; + +/* + * struct drm_client_funcs and setup code + */ + +static void psb_fbdev_client_unregister(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + + if (fb_helper->info) { + drm_fb_helper_unregister_info(fb_helper); + } else { + drm_fb_helper_unprepare(fb_helper); + drm_client_release(&fb_helper->client); + kfree(fb_helper); + } +} + +static int psb_fbdev_client_restore(struct drm_client_dev *client) +{ + drm_fb_helper_lastclose(client->dev); + + return 0; +} + +static int psb_fbdev_client_hotplug(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + struct drm_device *dev = client->dev; + int ret; + + if (dev->fb_helper) + return drm_fb_helper_hotplug_event(dev->fb_helper); + + ret = drm_fb_helper_init(dev, fb_helper); + if (ret) + goto err_drm_err; + + if (!drm_drv_uses_atomic_modeset(dev)) + drm_helper_disable_unused_functions(dev); + + ret = drm_fb_helper_initial_config(fb_helper); + if (ret) + goto err_drm_fb_helper_fini; + + return 0; + +err_drm_fb_helper_fini: + drm_fb_helper_fini(fb_helper); +err_drm_err: + drm_err(dev, "Failed to setup gma500 fbdev emulation (ret=%d)\n", ret); + return ret; +} + +static const struct drm_client_funcs psb_fbdev_client_funcs = { + .owner = THIS_MODULE, + .unregister = psb_fbdev_client_unregister, + .restore = psb_fbdev_client_restore, + .hotplug = psb_fbdev_client_hotplug, +}; + +void psb_fbdev_setup(struct drm_psb_private *dev_priv) +{ + struct drm_device *dev = &dev_priv->dev; + struct drm_fb_helper *fb_helper; + int ret; + + fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); + if (!fb_helper) + return; + drm_fb_helper_prepare(dev, fb_helper, 32, &psb_fbdev_fb_helper_funcs); + + ret = drm_client_init(dev, &fb_helper->client, "fbdev-gma500", &psb_fbdev_client_funcs); + if (ret) { + drm_err(dev, "Failed to register client: %d\n", ret); + goto err_drm_fb_helper_unprepare; + } + + ret = psb_fbdev_client_hotplug(&fb_helper->client); + if (ret) + drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); + + drm_client_register(&fb_helper->client); + + return; + +err_drm_fb_helper_unprepare: + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); +} diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 50611eb7f134..1a374702b696 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -5,158 +5,18 @@ * **************************************************************************/ -#include <linux/console.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/pfn_t.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/tty.h> - -#include <drm/drm.h> -#include <drm/drm_crtc.h> -#include <drm/drm_crtc_helper.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_fourcc.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" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" static const struct drm_framebuffer_funcs psb_fb_funcs = { .destroy = drm_gem_fb_destroy, .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; - vm_flags_set(vma, 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 @@ -207,11 +67,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; @@ -229,93 +87,6 @@ static struct drm_framebuffer *psb_framebuffer_create } /** - * 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 * @filp: client file @@ -346,108 +117,8 @@ 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, }; static void psb_setup_outputs(struct drm_device *dev) @@ -515,7 +186,6 @@ void psb_modeset_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - struct pci_dev *pdev = to_pci_dev(dev->dev); int i; if (drmm_mode_config_init(dev)) @@ -526,10 +196,6 @@ void psb_modeset_init(struct drm_device *dev) dev->mode_config.funcs = &psb_mode_funcs; - /* set memory base */ - /* Oaktrail and Poulsbo should use BAR 2*/ - pci_read_config_dword(pdev, PSB_BSM, (u32 *)&(dev_priv->fb_base)); - /* num pipes is 2 for PSB but 1 for Mrst */ for (i = 0; i < dev_priv->num_pipe; i++) psb_intel_crtc_init(dev, i, mode_dev); @@ -550,6 +216,5 @@ void psb_modeset_cleanup(struct drm_device *dev) struct drm_psb_private *dev_priv = to_drm_psb_private(dev); if (dev_priv->modeset) { drm_kms_helper_poll_fini(dev); - psb_fbdev_fini(dev); } } diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index cd9c73f5a64a..2ce96b1b9c74 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -21,7 +21,6 @@ #include <drm/drm.h> #include <drm/drm_aperture.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> #include <drm/drm_pciids.h> @@ -387,7 +386,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ psb_modeset_init(dev); - psb_fbdev_init(dev); drm_kms_helper_poll_init(dev); /* Only add backlight support if we have LVDS or MIPI output */ @@ -452,6 +450,8 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; + psb_fbdev_setup(dev_priv); + return 0; } @@ -477,7 +477,6 @@ static const struct file_operations psb_gem_fops = { static const struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM, - .lastclose = drm_fb_helper_lastclose, .num_ioctls = ARRAY_SIZE(psb_ioctls), diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index a5df6d2f2cab..f7f709df99b4 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -193,8 +193,6 @@ #define KSEL_BYPASS_25 6 #define KSEL_BYPASS_83_100 7 -struct drm_fb_helper; - struct opregion_header; struct opregion_acpi; struct opregion_swsci; @@ -522,9 +520,6 @@ struct drm_psb_private { uint32_t blc_adj1; uint32_t blc_adj2; - struct drm_fb_helper *fb_helper; - resource_size_t fb_base; - bool dsr_enable; u32 dsr_fb_update; bool dpi_panel_on[3]; @@ -610,7 +605,19 @@ 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); -extern int psb_fbdev_init(struct drm_device *dev); + +/* framebuffer */ +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) +void psb_fbdev_setup(struct drm_psb_private *dev_priv); +#else +static inline void psb_fbdev_setup(struct drm_psb_private *dev_priv) +{ } +#endif /* backlight.c */ int gma_backlight_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index d421031462df..343c51250207 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c @@ -32,17 +32,6 @@ static inline u32 gma_pipestat(int pipe) BUG(); } -static inline u32 gma_pipe_event(int pipe) -{ - if (pipe == 0) - return _PSB_PIPEA_EVENT_FLAG; - if (pipe == 1) - return _MDFLD_PIPEB_EVENT_FLAG; - if (pipe == 2) - return _MDFLD_PIPEC_EVENT_FLAG; - BUG(); -} - static inline u32 gma_pipeconf(int pipe) { if (pipe == 0) |