drm: add simpledrm driver
Subsystems (14)
v5 cover drm: add simpledrm driver
Hey
On request of Noralf, I picked up the patches and prepared v5. Works fine with Xorg, if configured according to:
https://lists.freedesktop.org/archives/dri-devel/2014-January/052777.html
If anyone knows how to make Xorg pick it up dynamically without such a static configuration, please let me know.
Thanks
David
David Herrmann (7):
x86/sysfb: add support for 64bit EFI lfb_base x86/sysfb: fix lfb_size calculation of/platform: expose of_platform_device_destroy()
video: add generic framebuffer eviction
drm: switch to sysfb_evict_conflicts()
drm: add SimpleDRM driver
drm/simpledrm: add fbdev fallback support
MAINTAINERS | 6 + arch/x86/kernel/sysfb_simplefb.c | 39 ++- drivers/gpu/drm/Kconfig | 3 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 24 +- drivers/gpu/drm/bochs/bochs_drv.c | 19 +- drivers/gpu/drm/i915/i915_drv.c | 73 +--- drivers/gpu/drm/mgag200/mgag200_drv.c | 27 +- drivers/gpu/drm/mgag200/mgag200_main.c | 9 - drivers/gpu/drm/nouveau/nouveau_drm.c | 33 +- drivers/gpu/drm/radeon/radeon_drv.c | 24 +- drivers/gpu/drm/simpledrm/Kconfig | 19 ++ drivers/gpu/drm/simpledrm/Makefile | 9 + drivers/gpu/drm/simpledrm/simpledrm.h | 91 +++++ drivers/gpu/drm/simpledrm/simpledrm_damage.c | 194 +++++++++++ drivers/gpu/drm/simpledrm/simpledrm_drv.c | 477 +++++++++++++++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_fbdev.c | 143 ++++++++ drivers/gpu/drm/simpledrm/simpledrm_gem.c | 109 ++++++ drivers/gpu/drm/simpledrm/simpledrm_kms.c | 270 +++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_of.c | 265 +++++++++++++++ drivers/gpu/drm/sun4i/sun4i_drv.c | 24 +- drivers/gpu/drm/vc4/vc4_drv.c | 25 +- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 24 +- drivers/of/platform.c | 35 +- drivers/video/Kconfig | 4 + drivers/video/Makefile | 1 + drivers/video/sysfb.c | 327 ++++++++++++++++++ include/linux/of_platform.h | 1 + include/linux/sysfb.h | 34 ++ 29 files changed, 2054 insertions(+), 256 deletions(-) create mode 100644 drivers/gpu/drm/simpledrm/Kconfig create mode 100644 drivers/gpu/drm/simpledrm/Makefile create mode 100644 drivers/gpu/drm/simpledrm/simpledrm.h create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_damage.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_drv.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_fbdev.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_gem.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_kms.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_of.c create mode 100644 drivers/video/sysfb.c create mode 100644 include/linux/sysfb.h
Signature · 6 lines
2.9.3 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v5 1/7 x86/sysfb: add support for 64bit EFI lfb_base
The screen_info object was extended to support 64bit lfb_base addresses in:
commit ae2ee627dc87a70910de91b791b3cd0e9c6facdd
Author: Matt Fleming <[email protected]>
Date: Tue Aug 25 16:32:55 2015 +0100
efifb: Add support for 64-bit frame buffer addresses
However, the x86 simple-framebuffer setup code never made use of it. Fix it to properly assemble and verify the lfb_base before advertising simple-framebuffer devices.
In particular, this means if VIDEO_CAPABILITY_64BIT_BASE is set, the screen_info->ext_lfb_base field will contain the upper 32bit of the actual lfb_base. Make sure the address is not 0 (i.e., unset), as well as does not overflow the physical address type.
--- arch/x86/kernel/sysfb_simplefb.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
arch/x86/kernel/sysfb_simplefb.c +16 -2
@@ -67,6 +67,20 @@ __init int create_simplefb(const struct screen_info *si,struct platform_device *pd;struct resource res;unsigned long len; +u64 base; + +/* +* If the 64BIT_BASE capability is set, ext_lfb_base will contain the +* upper half of the base address. Assemble the address, then make sure +* it is valid and we can actually access it. +*/ + base = si->lfb_base; +if (si->capabilities &VIDEO_CAPABILITY_64BIT_BASE ) + base |= (u64 )si->ext_lfb_base <<32 ; +if (!base || (u64 )(resource_size_t )base != base) { +printk (KERN_DEBUG "sysfb: inaccessible VRAM base\n" ); +return -EINVAL ; + }/* don't use lfb_size as it may contain the whole VMEM instead of only * the part that is occupied by the framebuffer */
@@ -81,8 +95,8 @@ __init int create_simplefb(const struct screen_info *si,memset (&res,0 ,sizeof (res)); res.flags =IORESOURCE_MEM |IORESOURCE_BUSY ; res.name = simplefb_resname; - res.start = si->lfb_base; - res.end = si->lfb_base + len -1 ; + res.start = base; + res.end = res.start + len -1 ;if (res.end <= res.start)return -EINVAL ;
Signature · 6 lines
2.9.3 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 1/7] x86/sysfb: add support for 64bit EFI lfb_base
Quoted 13 lines · David Herrmann
The
screen_infoobject was extended to support 64bitlfb_baseaddresses in:commit
ae2ee627dc87a70910de91b791b3cd0e9c6facdd
Author: Matt Fleming <[email protected]>
Date: Tue Aug 25 16:32:55 2015 +0100efifb: Add support for 64-bit frame buffer addresses
However, the x86 simple-framebuffer setup code never made use of it. Fix it to properly assemble and verify the
lfb_basebefore advertising simple-framebuffer devices.
Quoted 6 lines
In particular, this means if
VIDEO_CAPABILITY_64BIT_BASEis set, thescreen_info->ext_lfb_basefield will contain the upper 32bit of the actuallfb_base. Make sure the address is not 0 (i.e., unset), as well as does not overflow the physical address type.Signed-off-by David Herrmann <[email protected]>
Quoted 43 lines
--- arch/x86/kernel/sysfb_simplefb.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)arch/x86/kernel/sysfb_simplefb.c +16
-3@@ -67,6 +67,20 @@ __init int create_simplefb(const struct screen_info *si,struct platform_device *pd;struct resource res;unsigned long len; +u64 base; + +/* +* If the 64BIT_BASE capability is set, ext_lfb_base will contain the +* upper half of the base address. Assemble the address, then make sure +* it is valid and we can actually access it. +*/ + base = si->lfb_base; +if (si->capabilities &VIDEO_CAPABILITY_64BIT_BASE ) + base |= (u64 )si->ext_lfb_base <<32 ; +if (!base || (u64 )(resource_size_t )base != base) { +printk (KERN_DEBUG "sysfb: inaccessible VRAM base\n" ); +return -EINVAL ; + }/* don't use lfb_size as it may contain the whole VMEM instead of only * the part that is occupied by the framebuffer */ @@ -81,8 +95,8 @@ __init int create_simplefb(const struct screen_info *si,memset (&res,0 ,sizeof (res)); res.flags =IORESOURCE_MEM |IORESOURCE_BUSY ; res.name = simplefb_resname; - res.start = si->lfb_base; - res.end = si->lfb_base + len -1 ; + res.start = base; + res.end = res.start + len -1 ;if (res.end <= res.start)return -EINVAL ; --2.9.3
Quoted 4 lines
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v5 2/7 x86/sysfb: fix lfb_size calculation
In reply to David HerrmannThe screen_info.lfb_size field is shifted by 16 bits *only* in case of VBE. This has historical reasons since VBE advertised it similarly. However, in case of EFI framebuffers, the size is no longer shifted. Fix the x86 simple-framebuffer setup code to use the correct size in the non-VBE case.
While at it, avoid variable abbreviations and rename 'len' to 'length', and use the correct types matching the screen_info definition.
--- arch/x86/kernel/sysfb_simplefb.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)
arch/x86/kernel/sysfb_simplefb.c +17 -8
@@ -66,8 +66,8 @@ __init int create_simplefb(const struct screen_info *si, {struct platform_device *pd;struct resource res; -unsigned long len; -u64 base; +u64 base, size; +u32 length;/* * If the 64BIT_BASE capability is set, ext_lfb_base will contain the
@@ -82,11 +82,20 @@ __init int create_simplefb(const struct screen_info *si,return -EINVAL ; } -/* don't use lfb_size as it may contain the whole VMEM instead of only -* the part that is occupied by the framebuffer */ - len = mode->height * mode->stride; - len =PAGE_ALIGN (len); -if (len > (u64 )si->lfb_size <<16 ) { +/* +* Don't use lfb_size as IORESOURCE size, since it may contain the +* entire VMEM, and thus require huge mappings. Use just the part we +* need, that is, the part where the framebuffer is located. But verify +* that it does not exceed the advertised VMEM. +* Note that in case of VBE, the lfb_size is shifted by 16 bits for +* historical reasons. +*/ + size = si->lfb_size; +if (si->orig_video_isVGA ==VIDEO_TYPE_VLFB ) + size <<=16 ; + length = mode->height * mode->stride; + length =PAGE_ALIGN (length); +if (length > size) {printk (KERN_WARNING "sysfb: VRAM smaller than advertised\n" );return -EINVAL ; }
@@ -96,7 +105,7 @@ __init int create_simplefb(const struct screen_info *si, res.flags =IORESOURCE_MEM |IORESOURCE_BUSY ; res.name = simplefb_resname; res.start = base; - res.end = res.start + len -1 ; + res.end = res.start + length -1 ;if (res.end <= res.start)return -EINVAL ;
Signature · 6 lines
2.9.3 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 2/7] x86/sysfb: fix lfb_size calculation
Quoted 10 lines · David Herrmann
The screen_info.lfb_size field is shifted by 16 bits *only* in case of VBE. This has historical reasons since VBE advertised it similarly. However, in case of EFI framebuffers, the size is no longer shifted. Fix the x86 simple-framebuffer setup code to use the correct size in the non-VBE case.
While at it, avoid variable abbreviations and rename 'len' to 'length', and use the correct types matching the
screen_infodefinition.Signed-off-by David Herrmann <[email protected]>
Quoted 57 lines
--- arch/x86/kernel/sysfb_simplefb.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)arch/x86/kernel/sysfb_simplefb.c +17
-9@@ -66,8 +66,8 @@ __init int create_simplefb(const struct screen_info *si, {struct platform_device *pd;struct resource res; -unsigned long len; -u64 base; +u64 base, size; +u32 length;/* * If the 64BIT_BASE capability is set, ext_lfb_base will contain the @@ -82,11 +82,20 @@ __init int create_simplefb(const struct screen_info *si,return -EINVAL ; } -/* don't use lfb_size as it may contain the whole VMEM instead of only -* the part that is occupied by the framebuffer */ - len = mode->height * mode->stride; - len =PAGE_ALIGN (len); -if (len > (u64 )si->lfb_size <<16 ) { +/* +* Don't use lfb_size as IORESOURCE size, since it may contain the +* entire VMEM, and thus require huge mappings. Use just the part we +* need, that is, the part where the framebuffer is located. But verify +* that it does not exceed the advertised VMEM. +* Note that in case of VBE, the lfb_size is shifted by 16 bits for +* historical reasons. +*/ + size = si->lfb_size; +if (si->orig_video_isVGA ==VIDEO_TYPE_VLFB ) + size <<=16 ; + length = mode->height * mode->stride; + length =PAGE_ALIGN (length); +if (length > size) {printk (KERN_WARNING "sysfb: VRAM smaller than advertised\n" );return -EINVAL ; }@@ -96,7 +105,7 @@ __init int create_simplefb(const struct screen_info *si, res.flags =IORESOURCE_MEM |IORESOURCE_BUSY ; res.name = simplefb_resname; res.start = base; - res.end = res.start + len -1 ; + res.end = res.start + length -1 ;if (res.end <= res.start)return -EINVAL ; --2.9.3
Quoted 4 lines
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v5 3/7 of/platform: expose of_platform_device_destroy()
In reply to David HerrmannWe already expose of_platform_device_create(), but give the caller no chance to revert its effect. Make sure we also provide the counterpart of_platform_device_destroy().
This requires a small refactoring, since so far the internal destructor is used as iterator to for_each_device(), but we don't want to expose it with the "void *data" parameter. So provide of_platform_device_depopulate() as new iterator, which calls into of_platform_device_destroy().
While at it, drop the unused 'children_left' argument by of_platform_notify(). It is a left-over that somehow was never removed.
--- drivers/of/platform.c | 35 ++++++++++++++++++++++++++--------- include/linux/of_platform.h | 1 + 2 files changed, 27 insertions(+), 9 deletions(-)
drivers/of/platform.c +26 -9
@@ -524,15 +524,18 @@ static int __init of_platform_default_populate_init(void)arch_initcall_sync (of_platform_default_populate_init);#endif -static int of_platform_device_destroy (struct device *dev,void *data) +/** +* of_platform_device_destroy - unregister an of_device +* @dev: device to unregister +* +* This is the inverse operation of of_platform_device_create(). It unregisters +* the passed device, if registered. +*/ +void of_platform_device_destroy (struct device *dev) {/* Do not touch devices not populated from the device tree */ if (!dev->of_node || !of_node_check_flag (dev->of_node,OF_POPULATED )) -return 0 ; - -/* Recurse for any nodes that were treated as busses */ -if (of_node_check_flag (dev->of_node,OF_POPULATED_BUS )) -device_for_each_child (dev,NULL , of_platform_device_destroy); +return ;if (dev->bus == &platform_bus_type)platform_device_unregister (to_platform_device (dev));
@@ -544,6 +547,20 @@ static int of_platform_device_destroy(struct device *dev, void *data)of_dma_deconfigure (dev);of_node_clear_flag (dev->of_node,OF_POPULATED );of_node_clear_flag (dev->of_node,OF_POPULATED_BUS ); +} +EXPORT_SYMBOL (of_platform_device_destroy); + +static int of_platform_device_depopulate (struct device *dev,void *data) +{ +/* Do not touch devices not populated from the device tree */ +if (!dev->of_node || !of_node_check_flag (dev->of_node,OF_POPULATED )) +return 0 ; + +/* Recurse for any nodes that were treated as busses */ +if (of_node_check_flag (dev->of_node,OF_POPULATED_BUS )) +device_for_each_child (dev,NULL , of_platform_device_depopulate); + +of_platform_device_destroy (dev);return 0 ; }
@@ -562,7 +579,8 @@ static int of_platform_device_destroy(struct device *dev, void *data)void of_platform_depopulate (struct device *parent) {if (parent->of_node &&of_node_check_flag (parent->of_node,OF_POPULATED_BUS )) { -device_for_each_child (parent,NULL , of_platform_device_destroy); +device_for_each_child (parent,NULL , + of_platform_device_depopulate);of_node_clear_flag (parent->of_node,OF_POPULATED_BUS ); } }
@@ -574,7 +592,6 @@ static int of_platform_notify(struct notifier_block *nb, {struct of_reconfig_data *rd = arg;struct platform_device *pdev_parent, *pdev; -bool children_left;switch (of_reconfig_get_state_change (action, rd)) {case OF_RECONFIG_CHANGE_ADD :
@@ -612,7 +629,7 @@ static int of_platform_notify(struct notifier_block *nb,return NOTIFY_OK ;/* no? not meant for us */ /* unregister takes one ref away */ -of_platform_device_destroy (&pdev->dev, &children_left); +of_platform_device_depopulate (&pdev->dev,NULL );/* and put the reference of the find */ of_dev_put (pdev);
include/linux/of_platform.h +1 -0
@@ -63,6 +63,7 @@ extern struct platform_device *of_find_device_by_node(struct device_node *np);extern struct platform_device *of_platform_device_create (struct device_node *np,const char *bus_id,struct device *parent); +extern void of_platform_device_destroy (struct device *dev); extern int of_platform_bus_probe(struct device_node *root, const struct of_device_id *matches,
Signature · 6 lines
2.9.3 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 3/7] of/platform: expose of_platform_device_destroy()
Quoted 10 lines · David Herrmann
We already expose
of_platform_device_create(), but give the caller no chance to revert its effect. Make sure we also provide the counterpartof_platform_device_destroy().This requires a small refactoring, since so far the internal destructor is used as iterator to
for_each_device(), but we don't want to expose it with the "void *data" parameter. So provideof_platform_device_depopulate()as new iterator, which calls intoof_platform_device_destroy().
Quoted 4 lines
While at it, drop the unused '
children_left' argument byof_platform_notify(). It is a left-over that somehow was never removed.Signed-off-by David Herrmann <[email protected]>
Quoted 97 lines
--- drivers/of/platform.c | 35 ++++++++++++++++++++++++++--------- include/linux/of_platform.h | 1 + 2 files changed, 27 insertions(+), 9 deletions(-)drivers/of/platform.c +26
-9@@ -524,15 +524,18 @@ static int __init of_platform_default_populate_init(void)arch_initcall_sync (of_platform_default_populate_init);#endif -static int of_platform_device_destroy (struct device *dev,void *data) +/** +* of_platform_device_destroy - unregister an of_device +* @dev: device to unregister +* +* This is the inverse operation of of_platform_device_create(). It unregisters +* the passed device, if registered. +*/ +void of_platform_device_destroy (struct device *dev) {/* Do not touch devices not populated from the device tree */ if (!dev->of_node || !of_node_check_flag (dev->of_node,OF_POPULATED )) -return 0 ; - -/* Recurse for any nodes that were treated as busses */ -if (of_node_check_flag (dev->of_node,OF_POPULATED_BUS )) -device_for_each_child (dev,NULL , of_platform_device_destroy); +return ;if (dev->bus == &platform_bus_type)platform_device_unregister (to_platform_device (dev));@@ -544,6 +547,20 @@ static int of_platform_device_destroy(struct device *dev, void *data)of_dma_deconfigure (dev);of_node_clear_flag (dev->of_node,OF_POPULATED );of_node_clear_flag (dev->of_node,OF_POPULATED_BUS ); +} +EXPORT_SYMBOL (of_platform_device_destroy); + +static int of_platform_device_depopulate (struct device *dev,void *data) +{ +/* Do not touch devices not populated from the device tree */ +if (!dev->of_node || !of_node_check_flag (dev->of_node,OF_POPULATED )) +return 0 ; + +/* Recurse for any nodes that were treated as busses */ +if (of_node_check_flag (dev->of_node,OF_POPULATED_BUS )) +device_for_each_child (dev,NULL , of_platform_device_depopulate); + +of_platform_device_destroy (dev);return 0 ; }@@ -562,7 +579,8 @@ static int of_platform_device_destroy(struct device *dev, void *data)void of_platform_depopulate (struct device *parent) {if (parent->of_node &&of_node_check_flag (parent->of_node,OF_POPULATED_BUS )) { -device_for_each_child (parent,NULL , of_platform_device_destroy); +device_for_each_child (parent,NULL , + of_platform_device_depopulate);of_node_clear_flag (parent->of_node,OF_POPULATED_BUS ); } }@@ -574,7 +592,6 @@ static int of_platform_notify(struct notifier_block *nb, {struct of_reconfig_data *rd = arg;struct platform_device *pdev_parent, *pdev; -bool children_left;switch (of_reconfig_get_state_change (action, rd)) {case OF_RECONFIG_CHANGE_ADD :@@ -612,7 +629,7 @@ static int of_platform_notify(struct notifier_block *nb,return NOTIFY_OK ;/* no? not meant for us */ /* unregister takes one ref away */ -of_platform_device_destroy (&pdev->dev, &children_left); +of_platform_device_depopulate (&pdev->dev,NULL );/* and put the reference of the find */ of_dev_put (pdev);include/linux/of_platform.h +1
-1@@ -63,6 +63,7 @@ extern struct platform_device *of_find_device_by_node(struct device_node *np);extern struct platform_device *of_platform_device_create (struct device_node *np,const char *bus_id,struct device *parent); +extern void of_platform_device_destroy (struct device *dev); extern int of_platform_bus_probe(struct device_node *root, const struct of_device_id *matches, --2.9.3
Quoted 4 lines
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v5 4/7 video: add generic framebuffer eviction
In reply to David HerrmannThere are several situations where we want hardware handover from an early boot GFX driver (e.g., vgacon, vesafb, efifb, simplefb) to a full fletched GFX driver (e.g., most DRM drivers). So far, we relied on remove_conflicting_framebuffers() to do this for us, however, this had a bunch of downsides:
o It only removes conflicting fbdev drivers. It does not drop vgacon, early boot console drivers, conflicting DRM drivers, etc.
o It only unloads the fbdev driver, it does not modify the underlying device or resources. In case of "screen_info" drivers (e.g., efifb) this is fine, since no resources are pinned. However, if the driver binds to a platform-device like "simple-framebuffer", we must make sure to unregister that device as well. Otherwise, pinned resources like IORESOURCE_MEM stay around, triggering WARN_ONs if the following driver requests those resources.
o It is only available if CONFIG_FB is selected.
This commit adds a new infrastructure that manages system-framebuffers (short: sysfb). The initial commit provides conflict-resolution for system-framebuffers. At its core it provides sysfb_evict_conflicts(), which implements conflict detection and removal for all known types of GFX driver hand-overs. So far, this includes platform-device removal, fbdev-firmware-device removal, vgacon removal and VBE detection. To further simplify the callers, it also provides helpers to figure out what hand-over to do, based on the device the new drivers binds to:
o PCI drivers can use sysfb_evict_conflicts_pci(), which will figure out the apertures automatically, and does VGA/VBE detection.
o Generic firmware drivers that might be shadowed at any address in memory can use sysfb_evict_conflicts_firmware(), basically removing *all* firmware framebuffers in effect.
This only adds the generic sysfb helpers. No users are converted, yet.
--- drivers/video/Kconfig | 4 + drivers/video/Makefile | 1 + drivers/video/sysfb.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sysfb.h | 34 +++++ 4 files changed, 366 insertions(+) create mode 100644 drivers/video/sysfb.c create mode 100644 include/linux/sysfb.h
drivers/video/Kconfig +4 -0
@@ -36,6 +36,10 @@ config VIDEOMODE_HELPERS config HDMI bool +config SYSFB + bool + select DUMMY_CONSOLE if VT + if VT source "drivers/video/console/Kconfig" endif
drivers/video/Makefile +1 -0
@@ -1,5 +1,6 @@ obj-$(CONFIG_VGASTATE) += vgastate.o obj-$(CONFIG_HDMI) += hdmi.o +obj-$(CONFIG_SYSFB) += sysfb.o obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/
drivers/video/sysfb.c new file +327 -0
327 lines not on this page · raw message
include/linux/sysfb.h new file +34 -0
@@ -0,0 +1,34 @@ +#ifndef __LINUX_SYSFB_H +#define __LINUX_SYSFB_H + +/* +* Copyright (C) 2013-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#include <linux/kernel.h> + +struct apertures_struct ; +struct pci_dev ; + +enum { +SYSFB_EVICT_PLATFORM = (1U <<0 ), +SYSFB_EVICT_FBDEV = (1U <<1 ), +SYSFB_EVICT_VGACON = (1U <<2 ), +SYSFB_EVICT_VBE = (1U <<3 ), +}; + +struct sysfb_evict_ctx { +struct apertures_struct *ap; +unsigned int flags; +}; + +int sysfb_evict_conflicts (struct sysfb_evict_ctx *ctx); +int sysfb_evict_conflicts_firmware (void ); +int sysfb_evict_conflicts_pci (struct pci_dev *pdev); + +#endif /* __LINUX_SYSFB_H */
Signature · 6 lines
2.9.3 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 4/7] video: add generic framebuffer eviction
Quoted 31 lines · David Herrmann
There are several situations where we want hardware handover from an early boot GFX driver (e.g., vgacon, vesafb, efifb, simplefb) to a full fletched GFX driver (e.g., most DRM drivers). So far, we relied on
remove_conflicting_framebuffers()to do this for us, however, this had a bunch of downsides:o It only removes conflicting fbdev drivers. It does not drop vgacon, early boot console drivers, conflicting DRM drivers, etc.
o It only unloads the fbdev driver, it does not modify the underlying device or resources. In case of "
screen_info" drivers (e.g., efifb) this is fine, since no resources are pinned. However, if the driver binds to a platform-device like "simple-framebuffer", we must make sure to unregister that device as well. Otherwise, pinned resources likeIORESOURCE_MEMstay around, triggeringWARN_ONsif the following driver requests those resources.o It is only available if
CONFIG_FBis selected.This commit adds a new infrastructure that manages system-framebuffers (short: sysfb). The initial commit provides conflict-resolution for system-framebuffers. At its core it provides
sysfb_evict_conflicts(), which implements conflict detection and removal for all known types of GFX driver hand-overs. So far, this includes platform-device removal, fbdev-firmware-device removal, vgacon removal and VBE detection. To further simplify the callers, it also provides helpers to figure out what hand-over to do, based on the device the new drivers binds to:o PCI drivers can use
sysfb_evict_conflicts_pci(), which will figure out the apertures automatically, and does VGA/VBE detection.
Quoted 7 lines
o Generic firmware drivers that might be shadowed at any address in memory can use
sysfb_evict_conflicts_firmware(), basically removing *all* firmware framebuffers in effect.This only adds the generic sysfb helpers. No users are converted, yet.
Signed-off-by David Herrmann <[email protected]>
Quoted 411 lines
--- drivers/video/Kconfig | 4 + drivers/video/Makefile | 1 + drivers/video/sysfb.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sysfb.h | 34 +++++ 4 files changed, 366 insertions(+) create mode 100644 drivers/video/sysfb.c create mode 100644 include/linux/sysfb.hdrivers/video/Kconfig +4
-0@@ -36,6 +36,10 @@ config VIDEOMODE_HELPERS config HDMI bool +config SYSFB + bool + select DUMMY_CONSOLE if VT + if VT source "drivers/video/console/Kconfig" endifdrivers/video/Makefile +1
-0@@ -1,5 +1,6 @@ obj-$(CONFIG_VGASTATE) += vgastate.o obj-$(CONFIG_HDMI) += hdmi.o +obj-$(CONFIG_SYSFB) += sysfb.o obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/drivers/video/sysfb.c new file +327
-0@@ -0,0 +1,327 @@ +/* +* Copyright (C) 2013-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#define pr_fmt (fmt) "sysfb: " fmt +#include <linux/console.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/export.h> +#include <linux/fb.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/sysfb.h> +#include <linux/vt.h> + +static bool sysfb_evict_match_resource (struct sysfb_evict_ctx *ctx, +struct resource *mem) +{ +struct aperture *g; +unsigned int i; + +for (i =0 ; i < ctx->ap->count; ++i) { + g = &ctx->ap->ranges[i]; + +if (mem->start == g->base) +return true; +if (mem->start >= g->base && mem->end < g->base + g->size) +return true; +if ((ctx->flags &SYSFB_EVICT_VBE ) && mem->start ==0xA0000 ) +return true; + } + +return false; +} + +static int sysfb_evict_platform_device (struct device *dev,void *userdata) +{ +struct sysfb_evict_ctx *ctx = userdata; +struct platform_device *pdev =to_platform_device (dev); +struct resource *mem; + +if (!pdev->name) +return 0 ; + +if (!strcmp (pdev->name,"simple-framebuffer" )) { + mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!mem) +return 0 ; +if (!sysfb_evict_match_resource (ctx, mem)) +return 0 ; + +#ifdef CONFIG_OF_ADDRESS +if (dev->of_node) +of_platform_device_destroy (dev); + else +#endif +if (dev_get_platdata (&pdev->dev)) +platform_device_del (pdev); + } + +return 0 ; +} + +static int sysfb_evict_platform (struct sysfb_evict_ctx *ctx) +{ +/* +* Early-boot architecture setup and boot-loarders sometimes create +* preliminary platform devices with a generic framebuffer setup. This +* allows graphics access during boot-up, without a real graphics +* driver loaded. However, once a real graphics driver takes over, we +* have to destroy those platform devices. In the legacy fbdev case, we +* just used to unload the fbdev driver. However, to make sure any kind +* of driver is unloaded, the platform-eviction code here simply +* removes any conflicting platform device directly. This causes any +* bound driver to be detached, and then removes the device entirely so +* it cannot be bound to later on. +* +* Please note that any such platform device must be registered by +* early architecture setup code. If they are registered after regular +* GFX drivers, this will fail horribly. +*/ + +static DEFINE_MUTEX (lock); +int ret; + +/* +* In case of static platform-devices, we must iterate the bus and +* remove them manually. We know that we're the only code that might +* remove them, so a simple static lock serializes all calls here. +*/ +mutex_lock (&lock); + ret =bus_for_each_dev (&platform_bus_type,NULL , ctx, + sysfb_evict_platform_device); +mutex_unlock (&lock); +return ret; +} + +static int sysfb_evict_fbdev (struct sysfb_evict_ctx *ctx) +{ +/* +* Usually, evicting platform devices should be enough to also trigger +* fbdev unloading. However, some legacy devices (e.g., uvesafb) have +* no platform devices that can be evicted, so we still fall back to +* the legacy fbdev removal code. Note that this only removes fbdev +* devices marked as FBINFO_MISC_FIRMWARE. Anything else is left +* untouched. +* +* As usual, this only works if the fbdev device is probed early, +* before any real GFX driver wants to take over. +*/ + +int ret =0 ; + +#ifdef CONFIG_FB + ret =remove_conflicting_framebuffers (ctx->ap,"sysfb" , + ctx->flags &SYSFB_EVICT_VBE ); +#endif + +return ret; +} + +static int sysfb_evict_vgacon (struct sysfb_evict_ctx *ctx) +{ +/* +* The VGACON console driver pokes at VGA registers randomly. If a GFX +* driver cannot keep the VGA support alive, it better makes sure to +* unload VGACON before probing. +* +* Unloading VGACON requires us to first force dummycon to take over +* from vgacon (but only if vgacon is really in use), followed by a +* deregistration of vgacon. Note that this prevents vgacon from being +* used again after the GFX driver is unloaded. But that is usually +* fine, since VGA state is rarely restored on driver-unload, anyway. +* +* Note that we rely on VGACON to be probed in early boot (actually +* done by ARCH setup code). If it is probed after GFX drivers, this +* will fail horribly. You better make sure VGACON is probed early and +* GFX drivers are probed as normal modules. +*/ + +int ret =0 ; + +#ifdef CONFIG_VGA_CONSOLE +console_lock (); +if (con_is_bound (&vga_con)) + ret =do_take_over_console (&dummy_con,0 , +MAX_NR_CONSOLES -1 ,1 ); +if (ret ==0 ) { + ret =do_unregister_con_driver (&vga_con); +if (ret == -ENODEV )/* ignore "already unregistered" */ + ret =0 ; + } +console_unlock (); +#endif + +return ret; +} + +/** +* sysfb_evict_conflicts - remove any conflicting system-framebuffers +* @ctx: eviction context +* +* This function evicts any conflicting system-framebuffers and their bound +* drivers, according to the data given in @ctx. +* +* Depending on @ctx->flags, the following operations are performed: +* +* SYSFB_EVICT_PLATFORM: Firmware framebuffer platform devices (eg., +* 'simple-framebuffer') that overlap @ctx are removed +* from the system, causing drivers to be unbound. +* If SYSFB_EVICT_VBE is given, this also affects +* devices that own the VGA region. +* +* SYSFB_EVICT_FBDEV: Any firmware fbdev drivers that overlap @ctx are +* unloaded. +* Furthermore, if SYSFB_EVICT_VBE is given as well, any +* fbdev driver that maps the VGA region is unloaded. +* +* SYSFB_EVICT_VGACON: The vgacon console driver is unbound and unregistered. +* +* This might call into fbdev driver unregistration, or even device_del() on +* some buses. Hence, make sure you call this from your top-level +* probe-callbacks, rather than with any gfx-subsystem locks held. +* +* RETURNS: +* 0 on success, negative error code on failure. +*/ +int sysfb_evict_conflicts (struct sysfb_evict_ctx *ctx) +{ +int ret; + +if (WARN_ON (!ctx || !ctx->ap)) +return -EINVAL ; + +pr_info ("removing conflicts (sysfb%s%s%s%s)\n" , + (ctx->flags &SYSFB_EVICT_PLATFORM ) ?", platform" :"" , + (ctx->flags &SYSFB_EVICT_FBDEV ) ?", fbdev" :"" , + (ctx->flags &SYSFB_EVICT_VGACON ) ?", vgacon" :"" , + (ctx->flags &SYSFB_EVICT_VBE ) ?", vbe" :"" ); + +if (ctx->flags &SYSFB_EVICT_PLATFORM ) { + ret =sysfb_evict_platform (ctx); +if (ret <0 ) +return ret; + } + +if (ctx->flags &SYSFB_EVICT_FBDEV ) { + ret =sysfb_evict_fbdev (ctx); +if (ret <0 ) +return ret; + } + +if (ctx->flags &SYSFB_EVICT_VGACON ) { + ret =sysfb_evict_vgacon (ctx); +if (ret <0 ) +return ret; + } + +return 0 ; +} +EXPORT_SYMBOL (sysfb_evict_conflicts); + +/** +* sysfb_evict_conflicts_firmware() - remove all firmware framebuffers +* +* This is similar to sysfb_evict_conflicts() but uses a fake aperture spanning +* the entire address-space. This is suitable for any GFX driver that just +* wants to get rid of all available firmware framebuffers. +* +* RETURNS: +* 0 on success, negative error code on failure. +*/ +int sysfb_evict_conflicts_firmware (void ) +{ +struct sysfb_evict_ctx ctx = {}; +int ret; + + ctx.ap =alloc_apertures (1 ); +if (!ctx.ap) +return -ENOMEM ; + + ctx.ap->ranges[0 ].base =0 ; + ctx.ap->ranges[0 ].size = ~0 ; + + ctx.flags |=SYSFB_EVICT_FBDEV |SYSFB_EVICT_PLATFORM ; + ret =sysfb_evict_conflicts (&ctx); + +kfree (ctx.ap); +return ret; +} +EXPORT_SYMBOL (sysfb_evict_conflicts_firmware); + +#ifdef CONFIG_PCI +/** +* sysfb_evict_conflicts_pci() - remove all system framebuffers conflicting +* with the given pci device +* @pdev: pci device +* +* This is similar to sysfb_evict_conflicts() but generates the eviction +* context based on the given pci device @pdev. +* +* RETURNS: +* 0 on success, negative error code on failure. +*/ +int sysfb_evict_conflicts_pci (struct pci_dev *pdev) +{ +struct sysfb_evict_ctx ctx = {}; +size_t i, n, offset; +int ret; + +/* +* If this device is used as primary VGA device, it is shadowed at the +* VBE base address, so make sure to include it in the apertures. +*/ +if (pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ) + ctx.flags |=SYSFB_EVICT_VBE ; + +/* +* If a device is a VGA device, make sure to kick out vgacon. We cannot +* rely on the IORESOURCE_ROM_SHADOW, since vgacon can switch between +* vga devices at runtime. So kick out vgacon anyway. +*/ +if ((pdev->class >>8 ) ==PCI_CLASS_DISPLAY_VGA ) + ctx.flags |=SYSFB_EVICT_VGACON ; + +/* +* Allocate apertures for all standard PCI resources. Skip them in case +* they are empty. +*/ + ctx.ap =alloc_apertures (PCI_STD_RESOURCE_END -PCI_STD_RESOURCES +1 ); +if (!ctx.ap) +return -ENOMEM ; + + offset =PCI_STD_RESOURCES ; +for (n =0 , i =0 ; i < ctx.ap->count; ++i) { +if (pci_resource_len (pdev, offset + i) <1 ) +continue ; + + ctx.ap->ranges[n].base =pci_resource_start (pdev, offset + i); + ctx.ap->ranges[n].size =pci_resource_len (pdev, offset + i); + ++n; + } + ctx.ap->count = n; + +/* +* Evict all matching fbdev devices, VBE devices if they shadow this +* device, vgacon if this is a vga device, and platform devices if they +* match. +*/ + ctx.flags |=SYSFB_EVICT_FBDEV |SYSFB_EVICT_PLATFORM ; + ret =sysfb_evict_conflicts (&ctx); + +kfree (ctx.ap); +return ret; +} +EXPORT_SYMBOL (sysfb_evict_conflicts_pci); +#endif /* CONFIG_PCI */ include/linux/sysfb.h new file +34
-1@@ -0,0 +1,34 @@ +#ifndef __LINUX_SYSFB_H +#define __LINUX_SYSFB_H + +/* +* Copyright (C) 2013-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#include <linux/kernel.h> + +struct apertures_struct ; +struct pci_dev ; + +enum { +SYSFB_EVICT_PLATFORM = (1U <<0 ), +SYSFB_EVICT_FBDEV = (1U <<1 ), +SYSFB_EVICT_VGACON = (1U <<2 ), +SYSFB_EVICT_VBE = (1U <<3 ), +}; + +struct sysfb_evict_ctx { +struct apertures_struct *ap; +unsigned int flags; +}; + +int sysfb_evict_conflicts (struct sysfb_evict_ctx *ctx); +int sysfb_evict_conflicts_firmware (void ); +int sysfb_evict_conflicts_pci (struct pci_dev *pdev); + +#endif /* __LINUX_SYSFB_H */ --2.9.3
Quoted 4 lines
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 4/7] video: add generic framebuffer eviction
In reply to David HerrmannDen 02.09.2016 10:22, skrev David Herrmann:
Quoted 124 lines
There are several situations where we want hardware handover from an early boot GFX driver (e.g., vgacon, vesafb, efifb, simplefb) to a full fletched GFX driver (e.g., most DRM drivers). So far, we relied on
remove_conflicting_framebuffers()to do this for us, however, this had a bunch of downsides:o It only removes conflicting fbdev drivers. It does not drop vgacon, early boot console drivers, conflicting DRM drivers, etc.
o It only unloads the fbdev driver, it does not modify the underlying device or resources. In case of "
screen_info" drivers (e.g., efifb) this is fine, since no resources are pinned. However, if the driver binds to a platform-device like "simple-framebuffer", we must make sure to unregister that device as well. Otherwise, pinned resources likeIORESOURCE_MEMstay around, triggeringWARN_ONsif the following driver requests those resources.o It is only available if
CONFIG_FBis selected.This commit adds a new infrastructure that manages system-framebuffers (short: sysfb). The initial commit provides conflict-resolution for system-framebuffers. At its core it provides
sysfb_evict_conflicts(), which implements conflict detection and removal for all known types of GFX driver hand-overs. So far, this includes platform-device removal, fbdev-firmware-device removal, vgacon removal and VBE detection. To further simplify the callers, it also provides helpers to figure out what hand-over to do, based on the device the new drivers binds to:o PCI drivers can use
sysfb_evict_conflicts_pci(), which will figure out the apertures automatically, and does VGA/VBE detection.o Generic firmware drivers that might be shadowed at any address in memory can use
sysfb_evict_conflicts_firmware(), basically removing *all* firmware framebuffers in effect.This only adds the generic sysfb helpers. No users are converted, yet.
Signed-off-by David Herrmann <[email protected]>--- drivers/video/Kconfig | 4 + drivers/video/Makefile | 1 + drivers/video/sysfb.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sysfb.h | 34 +++++ 4 files changed, 366 insertions(+)create mode 100644
drivers/video/sysfb.c
create mode 100644include/linux/sysfb.hdrivers/video/Kconfig +4
-0@@ -36,6 +36,10 @@ config VIDEOMODE_HELPERS config HDMI bool +config SYSFB + bool + select DUMMY_CONSOLE if VT + if VT source "drivers/video/console/Kconfig" endifdrivers/video/Makefile +1
-0@@ -1,5 +1,6 @@ obj-$(CONFIG_VGASTATE) += vgastate.o obj-$(CONFIG_HDMI) += hdmi.o +obj-$(CONFIG_SYSFB) += sysfb.o obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/drivers/video/sysfb.c new file +45
-0@@ -0,0 +1,327 @@ +/* +* Copyright (C) 2013-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#define pr_fmt (fmt) "sysfb: " fmt +#include <linux/console.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/export.h> +#include <linux/fb.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/sysfb.h> +#include <linux/vt.h> + +static bool sysfb_evict_match_resource (struct sysfb_evict_ctx *ctx, +struct resource *mem) +{ +struct aperture *g; +unsigned int i; + +for (i =0 ; i < ctx->ap->count; ++i) { + g = &ctx->ap->ranges[i]; + +if (mem->start == g->base) +return true; +if (mem->start >= g->base && mem->end < g->base + g->size) +return true; +if ((ctx->flags &SYSFB_EVICT_VBE ) && mem->start ==0xA0000 ) +return true; + } + +return false; +} +
drivers/video/sysfb.c line 55
Quoted 10 lines
drivers/video/sysfb.c new file +10
-0+static int sysfb_evict_platform_device (struct device *dev,void *userdata) +{ +struct sysfb_evict_ctx *ctx = userdata; +struct platform_device *pdev =to_platform_device (dev); +struct resource *mem; + +if (!pdev->name) +return 0 ; + +if (!strcmp (pdev->name,"simple-framebuffer" )) {
This doesn't work in my case where the device comes from DT and the name also contains the address: pdev->name=1e887000.framebuffer
This is one way of solving it:
if (!pdev->dev.driver || !pdev->dev.driver->name)
return 0;
if (!strcmp(pdev->dev.driver->name, "simple-framebuffer")) {Noralf.
Quoted 302 lines
drivers/video/sysfb.c new file +272
-0+ mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!mem) +return 0 ; +if (!sysfb_evict_match_resource (ctx, mem)) +return 0 ; + +#ifdef CONFIG_OF_ADDRESS +if (dev->of_node) +of_platform_device_destroy (dev); + else +#endif +if (dev_get_platdata (&pdev->dev)) +platform_device_del (pdev); + } + +return 0 ; +} + +static int sysfb_evict_platform (struct sysfb_evict_ctx *ctx) +{ +/* +* Early-boot architecture setup and boot-loarders sometimes create +* preliminary platform devices with a generic framebuffer setup. This +* allows graphics access during boot-up, without a real graphics +* driver loaded. However, once a real graphics driver takes over, we +* have to destroy those platform devices. In the legacy fbdev case, we +* just used to unload the fbdev driver. However, to make sure any kind +* of driver is unloaded, the platform-eviction code here simply +* removes any conflicting platform device directly. This causes any +* bound driver to be detached, and then removes the device entirely so +* it cannot be bound to later on. +* +* Please note that any such platform device must be registered by +* early architecture setup code. If they are registered after regular +* GFX drivers, this will fail horribly. +*/ + +static DEFINE_MUTEX (lock); +int ret; + +/* +* In case of static platform-devices, we must iterate the bus and +* remove them manually. We know that we're the only code that might +* remove them, so a simple static lock serializes all calls here. +*/ +mutex_lock (&lock); + ret =bus_for_each_dev (&platform_bus_type,NULL , ctx, + sysfb_evict_platform_device); +mutex_unlock (&lock); +return ret; +} + +static int sysfb_evict_fbdev (struct sysfb_evict_ctx *ctx) +{ +/* +* Usually, evicting platform devices should be enough to also trigger +* fbdev unloading. However, some legacy devices (e.g., uvesafb) have +* no platform devices that can be evicted, so we still fall back to +* the legacy fbdev removal code. Note that this only removes fbdev +* devices marked as FBINFO_MISC_FIRMWARE. Anything else is left +* untouched. +* +* As usual, this only works if the fbdev device is probed early, +* before any real GFX driver wants to take over. +*/ + +int ret =0 ; + +#ifdef CONFIG_FB + ret =remove_conflicting_framebuffers (ctx->ap,"sysfb" , + ctx->flags &SYSFB_EVICT_VBE ); +#endif + +return ret; +} + +static int sysfb_evict_vgacon (struct sysfb_evict_ctx *ctx) +{ +/* +* The VGACON console driver pokes at VGA registers randomly. If a GFX +* driver cannot keep the VGA support alive, it better makes sure to +* unload VGACON before probing. +* +* Unloading VGACON requires us to first force dummycon to take over +* from vgacon (but only if vgacon is really in use), followed by a +* deregistration of vgacon. Note that this prevents vgacon from being +* used again after the GFX driver is unloaded. But that is usually +* fine, since VGA state is rarely restored on driver-unload, anyway. +* +* Note that we rely on VGACON to be probed in early boot (actually +* done by ARCH setup code). If it is probed after GFX drivers, this +* will fail horribly. You better make sure VGACON is probed early and +* GFX drivers are probed as normal modules. +*/ + +int ret =0 ; + +#ifdef CONFIG_VGA_CONSOLE +console_lock (); +if (con_is_bound (&vga_con)) + ret =do_take_over_console (&dummy_con,0 , +MAX_NR_CONSOLES -1 ,1 ); +if (ret ==0 ) { + ret =do_unregister_con_driver (&vga_con); +if (ret == -ENODEV )/* ignore "already unregistered" */ + ret =0 ; + } +console_unlock (); +#endif + +return ret; +} + +/** +* sysfb_evict_conflicts - remove any conflicting system-framebuffers +* @ctx: eviction context +* +* This function evicts any conflicting system-framebuffers and their bound +* drivers, according to the data given in @ctx. +* +* Depending on @ctx->flags, the following operations are performed: +* +* SYSFB_EVICT_PLATFORM: Firmware framebuffer platform devices (eg., +* 'simple-framebuffer') that overlap @ctx are removed +* from the system, causing drivers to be unbound. +* If SYSFB_EVICT_VBE is given, this also affects +* devices that own the VGA region. +* +* SYSFB_EVICT_FBDEV: Any firmware fbdev drivers that overlap @ctx are +* unloaded. +* Furthermore, if SYSFB_EVICT_VBE is given as well, any +* fbdev driver that maps the VGA region is unloaded. +* +* SYSFB_EVICT_VGACON: The vgacon console driver is unbound and unregistered. +* +* This might call into fbdev driver unregistration, or even device_del() on +* some buses. Hence, make sure you call this from your top-level +* probe-callbacks, rather than with any gfx-subsystem locks held. +* +* RETURNS: +* 0 on success, negative error code on failure. +*/ +int sysfb_evict_conflicts (struct sysfb_evict_ctx *ctx) +{ +int ret; + +if (WARN_ON (!ctx || !ctx->ap)) +return -EINVAL ; + +pr_info ("removing conflicts (sysfb%s%s%s%s)\n" , + (ctx->flags &SYSFB_EVICT_PLATFORM ) ?", platform" :"" , + (ctx->flags &SYSFB_EVICT_FBDEV ) ?", fbdev" :"" , + (ctx->flags &SYSFB_EVICT_VGACON ) ?", vgacon" :"" , + (ctx->flags &SYSFB_EVICT_VBE ) ?", vbe" :"" ); + +if (ctx->flags &SYSFB_EVICT_PLATFORM ) { + ret =sysfb_evict_platform (ctx); +if (ret <0 ) +return ret; + } + +if (ctx->flags &SYSFB_EVICT_FBDEV ) { + ret =sysfb_evict_fbdev (ctx); +if (ret <0 ) +return ret; + } + +if (ctx->flags &SYSFB_EVICT_VGACON ) { + ret =sysfb_evict_vgacon (ctx); +if (ret <0 ) +return ret; + } + +return 0 ; +} +EXPORT_SYMBOL (sysfb_evict_conflicts); + +/** +* sysfb_evict_conflicts_firmware() - remove all firmware framebuffers +* +* This is similar to sysfb_evict_conflicts() but uses a fake aperture spanning +* the entire address-space. This is suitable for any GFX driver that just +* wants to get rid of all available firmware framebuffers. +* +* RETURNS: +* 0 on success, negative error code on failure. +*/ +int sysfb_evict_conflicts_firmware (void ) +{ +struct sysfb_evict_ctx ctx = {}; +int ret; + + ctx.ap =alloc_apertures (1 ); +if (!ctx.ap) +return -ENOMEM ; + + ctx.ap->ranges[0 ].base =0 ; + ctx.ap->ranges[0 ].size = ~0 ; + + ctx.flags |=SYSFB_EVICT_FBDEV |SYSFB_EVICT_PLATFORM ; + ret =sysfb_evict_conflicts (&ctx); + +kfree (ctx.ap); +return ret; +} +EXPORT_SYMBOL (sysfb_evict_conflicts_firmware); + +#ifdef CONFIG_PCI +/** +* sysfb_evict_conflicts_pci() - remove all system framebuffers conflicting +* with the given pci device +* @pdev: pci device +* +* This is similar to sysfb_evict_conflicts() but generates the eviction +* context based on the given pci device @pdev. +* +* RETURNS: +* 0 on success, negative error code on failure. +*/ +int sysfb_evict_conflicts_pci (struct pci_dev *pdev) +{ +struct sysfb_evict_ctx ctx = {}; +size_t i, n, offset; +int ret; + +/* +* If this device is used as primary VGA device, it is shadowed at the +* VBE base address, so make sure to include it in the apertures. +*/ +if (pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ) + ctx.flags |=SYSFB_EVICT_VBE ; + +/* +* If a device is a VGA device, make sure to kick out vgacon. We cannot +* rely on the IORESOURCE_ROM_SHADOW, since vgacon can switch between +* vga devices at runtime. So kick out vgacon anyway. +*/ +if ((pdev->class >>8 ) ==PCI_CLASS_DISPLAY_VGA ) + ctx.flags |=SYSFB_EVICT_VGACON ; + +/* +* Allocate apertures for all standard PCI resources. Skip them in case +* they are empty. +*/ + ctx.ap =alloc_apertures (PCI_STD_RESOURCE_END -PCI_STD_RESOURCES +1 ); +if (!ctx.ap) +return -ENOMEM ; + + offset =PCI_STD_RESOURCES ; +for (n =0 , i =0 ; i < ctx.ap->count; ++i) { +if (pci_resource_len (pdev, offset + i) <1 ) +continue ; + + ctx.ap->ranges[n].base =pci_resource_start (pdev, offset + i); + ctx.ap->ranges[n].size =pci_resource_len (pdev, offset + i); + ++n; + } + ctx.ap->count = n; + +/* +* Evict all matching fbdev devices, VBE devices if they shadow this +* device, vgacon if this is a vga device, and platform devices if they +* match. +*/ + ctx.flags |=SYSFB_EVICT_FBDEV |SYSFB_EVICT_PLATFORM ; + ret =sysfb_evict_conflicts (&ctx); + +kfree (ctx.ap); +return ret; +} +EXPORT_SYMBOL (sysfb_evict_conflicts_pci); +#endif /* CONFIG_PCI */ include/linux/sysfb.h new file +24
-0@@ -0,0 +1,34 @@ +#ifndef __LINUX_SYSFB_H +#define __LINUX_SYSFB_H + +/* +* Copyright (C) 2013-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#include <linux/kernel.h> + +struct apertures_struct ; +struct pci_dev ; + +enum { +SYSFB_EVICT_PLATFORM = (1U <<0 ), +SYSFB_EVICT_FBDEV = (1U <<1 ), +SYSFB_EVICT_VGACON = (1U <<2 ), +SYSFB_EVICT_VBE = (1U <<3 ), +}; +
include/linux/sysfb.h line 34
Quoted 10 lines
include/linux/sysfb.h new file +10
-0+struct sysfb_evict_ctx { +struct apertures_struct *ap; +unsigned int flags; +}; + +int sysfb_evict_conflicts (struct sysfb_evict_ctx *ctx); +int sysfb_evict_conflicts_firmware (void ); +int sysfb_evict_conflicts_pci (struct pci_dev *pdev); + +#endif /* __LINUX_SYSFB_H */
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 4/7] video: add generic framebuffer eviction
Hi
Quoted 147 lines · Noralf Trønnes
Den 02.09.2016 10:22, skrev David Herrmann:
Quoted 131 lines
There are several situations where we want hardware handover from an early boot GFX driver (e.g., vgacon, vesafb, efifb, simplefb) to a full fletched GFX driver (e.g., most DRM drivers). So far, we relied on
remove_conflicting_framebuffers()to do this for us, however, this had a bunch of downsides:o It only removes conflicting fbdev drivers. It does not drop vgacon, early boot console drivers, conflicting DRM drivers, etc.
o It only unloads the fbdev driver, it does not modify the underlying device or resources. In case of "
screen_info" drivers (e.g., efifb) this is fine, since no resources are pinned. However, if the driver binds to a platform-device like "simple-framebuffer", we must make sure to unregister that device as well. Otherwise, pinned resources likeIORESOURCE_MEMstay around, triggeringWARN_ONsif the following driver requests those resources.o It is only available if
CONFIG_FBis selected.This commit adds a new infrastructure that manages system-framebuffers (short: sysfb). The initial commit provides conflict-resolution for system-framebuffers. At its core it provides
sysfb_evict_conflicts(), which implements conflict detection and removal for all known types of GFX driver hand-overs. So far, this includes platform-device removal, fbdev-firmware-device removal, vgacon removal and VBE detection. To further simplify the callers, it also provides helpers to figure out what hand-over to do, based on the device the new drivers binds to:o PCI drivers can use
sysfb_evict_conflicts_pci(), which will figure
out
the apertures automatically, and does VGA/VBE detection.o Generic firmware drivers that might be shadowed at any address in memory can use
sysfb_evict_conflicts_firmware(), basically removing *all* firmware framebuffers in effect.This only adds the generic sysfb helpers. No users are converted, yet.
Signed-off-by David Herrmann <[email protected]>--- drivers/video/Kconfig | 4 + drivers/video/Makefile | 1 + drivers/video/sysfb.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sysfb.h | 34 +++++ 4 files changed, 366 insertions(+)create mode 100644
drivers/video/sysfb.c
create mode 100644include/linux/sysfb.hdrivers/video/Kconfig +3
-0@@ -36,6 +36,10 @@ config VIDEOMODE_HELPERS config HDMI bool +config SYSFB + bool + select DUMMY_CONSOLE if VT + if VT source "drivers/video/console/Kconfig" endifdrivers/video/Makefile +1
-0@@ -1,5 +1,6 @@ obj-$(CONFIG_VGASTATE) += vgastate.o obj-$(CONFIG_HDMI) += hdmi.o +obj-$(CONFIG_SYSFB) += sysfb.o obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/drivers/video/sysfb.c new file +4
-0@@ -0,0 +1,327 @@ +/* +* Copyright (C) 2013-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ */drivers/video/sysfb.c new file +31
-0+ +#define pr_fmt(fmt) "sysfb: " fmt +#include <linux/console.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/export.h> +#include <linux/fb.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/sysfb.h> +#include <linux/vt.h> + +static bool sysfb_evict_match_resource(struct sysfb_evict_ctx *ctx, + struct resource *mem) +{ + struct aperture *g; + unsigned int i; + + for (i = 0; i < ctx->ap->count; ++i) { + g = &ctx->ap->ranges[i]; + + if (mem->start == g->base) + return true; + if (mem->start >= g->base && mem->end < g->base + g->size) + return true; + if ((ctx->flags & SYSFB_EVICT_VBE) && mem->start ==
0xA0000)drivers/video/sysfb.c new file +7
-0+return true; + } + +return false; +} + +static int sysfb_evict_platform_device(struct device *dev, void*userdata)
drivers/video/sysfb.c
Quoted 9 lines
drivers/video/sysfb.c new file +9
-0+{ +struct sysfb_evict_ctx *ctx = userdata; +struct platform_device *pdev =to_platform_device (dev); +struct resource *mem; + +if (!pdev->name) +return 0 ; + +if (!strcmp (pdev->name,"simple-framebuffer" )) {This doesn't work in my case where the device comes from DT and the name also contains the address: pdev->name=1e887000.framebuffer
Quoted 6 lines
This is one way of solving it:
if (!pdev->dev.driver || !pdev->dev.driver->name) return 0; if (!strcmp(pdev->dev.driver->name, "simple-framebuffer")) {
Thanks for the hint, but this would skip devices that are not bound. How about the attached hunk?
Thanks
David
drivers/video/sysfb.c +2 -4
@@ -50,10 +50,8 @@ static int sysfb_evict_platform_devicestruct platform_device *pdev =to_platform_device (dev);struct resource *mem; -if (!pdev->name) -return 0 ; - -if (!strcmp (pdev->name,"simple-framebuffer" )) { +if ((pdev->name && !strcmp (pdev->name,"simple-framebuffer" )) || +of_device_is_compatible (pdev->dev.of_node,"simple-framebuffer" )) { mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 );if (!mem)return 0 ;
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 4/7] video: add generic framebuffer eviction
Den 05.09.2016 13:19, skrev David Herrmann:
Quoted 167 lines
Hi
Quoted 144 lines · Noralf Trønnes
Den 02.09.2016 10:22, skrev David Herrmann:
Quoted 130 lines
There are several situations where we want hardware handover from an early boot GFX driver (e.g., vgacon, vesafb, efifb, simplefb) to a full fletched GFX driver (e.g., most DRM drivers). So far, we relied on
remove_conflicting_framebuffers()to do this for us, however, this had a bunch of downsides:o It only removes conflicting fbdev drivers. It does not drop vgacon, early boot console drivers, conflicting DRM drivers, etc.
o It only unloads the fbdev driver, it does not modify the underlying device or resources. In case of "
screen_info" drivers (e.g., efifb) this is fine, since no resources are pinned. However, if the driver binds to a platform-device like "simple-framebuffer", we must make sure to unregister that device as well. Otherwise, pinned resources likeIORESOURCE_MEMstay around, triggeringWARN_ONsif the following driver requests those resources.o It is only available if
CONFIG_FBis selected.This commit adds a new infrastructure that manages system-framebuffers (short: sysfb). The initial commit provides conflict-resolution for system-framebuffers. At its core it provides
sysfb_evict_conflicts(), which implements conflict detection and removal for all known types of GFX driver hand-overs. So far, this includes platform-device removal, fbdev-firmware-device removal, vgacon removal and VBE detection. To further simplify the callers, it also provides helpers to figure out what hand-over to do, based on the device the new drivers binds to:o PCI drivers can use
sysfb_evict_conflicts_pci(), which will figure
out
the apertures automatically, and does VGA/VBE detection.o Generic firmware drivers that might be shadowed at any address in memory can use
sysfb_evict_conflicts_firmware(), basically removing *all* firmware framebuffers in effect.This only adds the generic sysfb helpers. No users are converted, yet.
Signed-off-by David Herrmann <[email protected]>--- drivers/video/Kconfig | 4 + drivers/video/Makefile | 1 + drivers/video/sysfb.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sysfb.h | 34 +++++ 4 files changed, 366 insertions(+)create mode 100644
drivers/video/sysfb.c
create mode 100644include/linux/sysfb.hdrivers/video/Kconfig +3
-0@@ -36,6 +36,10 @@ config VIDEOMODE_HELPERS config HDMI bool +config SYSFB + bool + select DUMMY_CONSOLE if VT + if VT source "drivers/video/console/Kconfig" endifdrivers/video/Makefile +1
-0@@ -1,5 +1,6 @@ obj-$(CONFIG_VGASTATE) += vgastate.o obj-$(CONFIG_HDMI) += hdmi.o +obj-$(CONFIG_SYSFB) += sysfb.o obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/drivers/video/sysfb.c new file +4
-0@@ -0,0 +1,327 @@ +/* +* Copyright (C) 2013-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ */drivers/video/sysfb.c new file +31
-0+ +#define pr_fmt(fmt) "sysfb: " fmt +#include <linux/console.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/export.h> +#include <linux/fb.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/sysfb.h> +#include <linux/vt.h> + +static bool sysfb_evict_match_resource(struct sysfb_evict_ctx *ctx, + struct resource *mem) +{ + struct aperture *g; + unsigned int i; + + for (i = 0; i < ctx->ap->count; ++i) { + g = &ctx->ap->ranges[i]; + + if (mem->start == g->base) + return true; + if (mem->start >= g->base && mem->end < g->base + g->size) + return true; + if ((ctx->flags & SYSFB_EVICT_VBE) && mem->start ==
0xA0000)drivers/video/sysfb.c new file +7
-0+return true; + } + +return false; +} + +static int sysfb_evict_platform_device(struct device *dev, void*userdata)
drivers/video/sysfb.c
Quoted 9 lines
drivers/video/sysfb.c new file +9
-0+{ +struct sysfb_evict_ctx *ctx = userdata; +struct platform_device *pdev =to_platform_device (dev); +struct resource *mem; + +if (!pdev->name) +return 0 ; + +if (!strcmp (pdev->name,"simple-framebuffer" )) {This doesn't work in my case where the device comes from DT and the name also contains the address: pdev->name=1e887000.framebuffer
Quoted 6 lines
This is one way of solving it:
if (!pdev->dev.driver || !pdev->dev.driver->name) return 0; if (!strcmp(pdev->dev.driver->name, "simple-framebuffer")) {Thanks for the hint, but this would skip devices that are not bound. How about the attached hunk?
Thanks
Daviddrivers/video/sysfb.c +0
-0@@ -50,10 +50,8 @@ static int sysfb_evict_platform_devicestruct platform_device *pdev =to_platform_device (dev);struct resource *mem;
drivers/video/sysfb.c static int sysfb_evict_platform_device · line 57
Quoted 10 lines
drivers/video/sysfb.c +2
-4-if (!pdev->name) -return 0 ; - -if (!strcmp (pdev->name,"simple-framebuffer" )) { +if ((pdev->name && !strcmp (pdev->name,"simple-framebuffer" )) || +of_device_is_compatible (pdev->dev.of_node,"simple-framebuffer" )) { mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 );if (!mem)return 0 ;
This worked fine.
Noralf.
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v5 5/7 drm: switch to sysfb_evict_conflicts()
In reply to David HerrmannSwitch over all DRM drivers to use the new sysfb_evict_conflicts() infrastructure. The only non-trivial conversion is i915, since it does not make use of the generic PCI resources, but assembles the apertures via intel ggtt queries.
--- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 24 +---------- drivers/gpu/drm/bochs/bochs_drv.c | 19 +-------- drivers/gpu/drm/i915/i915_drv.c | 73 ++++++-------------------------- drivers/gpu/drm/mgag200/mgag200_drv.c | 27 +++--------- drivers/gpu/drm/mgag200/mgag200_main.c | 9 ---- drivers/gpu/drm/nouveau/nouveau_drm.c | 33 +++------------ drivers/gpu/drm/radeon/radeon_drv.c | 24 +---------- drivers/gpu/drm/sun4i/sun4i_drv.c | 24 +++-------- drivers/gpu/drm/vc4/vc4_drv.c | 25 +++-------- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 24 +---------- 11 files changed, 44 insertions(+), 239 deletions(-)
drivers/gpu/drm/Kconfig +1 -0
@@ -12,6 +12,7 @@ menuconfig DRM select I2C select I2C_ALGOBIT select DMA_SHARED_BUFFER + select SYSFB help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +2 -22
@@ -38,6 +38,7 @@#include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/sysfb.h> #include <linux/vga_switcheroo.h> #include "drm_crtc_helper.h"
@@ -326,27 +327,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);static struct drm_driver kms_driver; -static int amdgpu_kick_out_firmware_fb (struct pci_dev *pdev) -{ -struct apertures_struct *ap; -bool primary = false; - - ap =alloc_apertures (1 ); -if (!ap) -return -ENOMEM ; - - ap->ranges[0 ].base =pci_resource_start (pdev,0 ); - ap->ranges[0 ].size =pci_resource_len (pdev,0 ); - -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; -#endif -remove_conflicting_framebuffers (ap,"amdgpudrmfb" , primary); -kfree (ap); - -return 0 ; -} -static int amdgpu_pci_probe (struct pci_dev *pdev,const struct pci_device_id *ent) {
@@ -368,7 +348,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,return ret;/* Get rid of things like offb */ - ret =amdgpu_kick_out_firmware_fb (pdev); + ret =sysfb_evict_conflicts_pci (pdev);if (ret)return ret;
drivers/gpu/drm/bochs/bochs_drv.c +2 -17
@@ -8,6 +8,7 @@#include <linux/mm.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/sysfb.h> #include "bochs.h"
@@ -143,28 +144,12 @@ static const struct dev_pm_ops bochs_pm_ops = {/* ---------------------------------------------------------------------- */ /* pci interface */ -static int bochs_kick_out_firmware_fb (struct pci_dev *pdev) -{ -struct apertures_struct *ap; - - ap =alloc_apertures (1 ); -if (!ap) -return -ENOMEM ; - - ap->ranges[0 ].base =pci_resource_start (pdev,0 ); - ap->ranges[0 ].size =pci_resource_len (pdev,0 ); -remove_conflicting_framebuffers (ap,"bochsdrmfb" , false); -kfree (ap); - -return 0 ; -} -static int bochs_pci_probe (struct pci_dev *pdev,const struct pci_device_id *ent) {int ret; - ret =bochs_kick_out_firmware_fb (pdev); + ret =sysfb_evict_conflicts_pci (pdev);if (ret)return ret;
drivers/gpu/drm/i915/i915_drv.c +14 -59
110 lines not on this page · raw message
drivers/gpu/drm/mgag200/mgag200_drv.c +6 -21
@@ -10,6 +10,7 @@*/ #include <linux/module.h> #include <linux/console.h> +#include <linux/sysfb.h> #include <drm/drmP.h> #include "mgag200_drv.h"
@@ -41,29 +42,13 @@ static const struct pci_device_id pciidlist[] = {MODULE_DEVICE_TABLE (pci, pciidlist); -static void mgag200_kick_out_firmware_fb (struct pci_dev *pdev) -{ -struct apertures_struct *ap; -bool primary = false; - - ap =alloc_apertures (1 ); -if (!ap) -return ; - - ap->ranges[0 ].base =pci_resource_start (pdev,0 ); - ap->ranges[0 ].size =pci_resource_len (pdev,0 ); - -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; -#endif -remove_conflicting_framebuffers (ap,"mgag200drmfb" , primary); -kfree (ap); -} - -static int mga_pci_probe (struct pci_dev *pdev,const struct pci_device_id *ent) { -mgag200_kick_out_firmware_fb (pdev); +int ret; + + ret =sysfb_evict_conflicts_pci (pdev); +if (ret <0 ) +return ret;return drm_get_pci_dev (pdev, ent, &driver); }
drivers/gpu/drm/mgag200/mgag200_main.c +0 -9
@@ -124,20 +124,11 @@ static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem)static int mga_vram_init (struct mga_device *mdev) {void __iomem *mem; -struct apertures_struct *aper =alloc_apertures (1 ); -if (!aper) -return -ENOMEM ;/* BAR 0 is VRAM */ mdev->mc.vram_base =pci_resource_start (mdev->dev->pdev,0 ); mdev->mc.vram_window =pci_resource_len (mdev->dev->pdev,0 ); - aper->ranges[0 ].base = mdev->mc.vram_base; - aper->ranges[0 ].size = mdev->mc.vram_window; - -remove_conflicting_framebuffers (aper,"mgafb" , true); -kfree (aper); -if (!devm_request_mem_region (mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window,"mgadrmfb_vram" )) {DRM_ERROR ("can't reserve VRAM\n" );
drivers/gpu/drm/nouveau/nouveau_drm.c +5 -28
@@ -27,6 +27,7 @@#include <linux/module.h> #include <linux/pci.h> #include <linux/pm_runtime.h> +#include <linux/sysfb.h> #include <linux/vga_switcheroo.h> #include "drmP.h"
@@ -310,8 +311,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent) {struct nvkm_device *device; -struct apertures_struct *aper; -bool boot = false;int ret;if (vga_switcheroo_client_probe_defer (pdev))
@@ -326,34 +325,12 @@ static int nouveau_drm_probe(struct pci_dev *pdev,nvkm_device_del (&device); -/* Remove conflicting drivers (vesafb, efifb etc). */ - aper =alloc_apertures (3 ); -if (!aper) -return -ENOMEM ; - - aper->ranges[0 ].base =pci_resource_start (pdev,1 ); - aper->ranges[0 ].size =pci_resource_len (pdev,1 ); - aper->count =1 ; - -if (pci_resource_len (pdev,2 )) { - aper->ranges[aper->count].base =pci_resource_start (pdev,2 ); - aper->ranges[aper->count].size =pci_resource_len (pdev,2 ); - aper->count++; - } - -if (pci_resource_len (pdev,3 )) { - aper->ranges[aper->count].base =pci_resource_start (pdev,3 ); - aper->ranges[aper->count].size =pci_resource_len (pdev,3 ); - aper->count++; +if (nouveau_modeset !=2 ) { + ret =sysfb_evict_conflicts_pci (pdev); +if (ret <0 ) +return ret; } -#ifdef CONFIG_X86 - boot = pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; -#endif -if (nouveau_modeset !=2 ) -remove_conflicting_framebuffers (aper,"nouveaufb" , boot); -kfree (aper); - ret =nvkm_device_pci_new (pdev, nouveau_config, nouveau_debug, true, true, ~0ULL , &device);if (ret)
drivers/gpu/drm/radeon/radeon_drv.c +2 -22
@@ -37,6 +37,7 @@#include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/sysfb.h> #include <linux/vga_switcheroo.h> #include <drm/drm_gem.h>
@@ -309,27 +310,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);static struct drm_driver kms_driver; -static int radeon_kick_out_firmware_fb (struct pci_dev *pdev) -{ -struct apertures_struct *ap; -bool primary = false; - - ap =alloc_apertures (1 ); -if (!ap) -return -ENOMEM ; - - ap->ranges[0 ].base =pci_resource_start (pdev,0 ); - ap->ranges[0 ].size =pci_resource_len (pdev,0 ); - -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; -#endif -remove_conflicting_framebuffers (ap,"radeondrmfb" , primary); -kfree (ap); - -return 0 ; -} -static int radeon_pci_probe (struct pci_dev *pdev,const struct pci_device_id *ent) {
@@ -347,7 +327,7 @@ static int radeon_pci_probe(struct pci_dev *pdev,return -EPROBE_DEFER ;/* Get rid of things like offb */ - ret =radeon_kick_out_firmware_fb (pdev); + ret =sysfb_evict_conflicts_pci (pdev);if (ret)return ret;
drivers/gpu/drm/sun4i/sun4i_drv.c +5 -19
@@ -12,6 +12,7 @@#include <linux/component.h> #include <linux/of_graph.h> +#include <linux/sysfb.h> #include <drm/drmP.h> #include <drm/drm_crtc_helper.h>
@@ -97,28 +98,16 @@ static struct drm_driver sun4i_drv_driver = { .disable_vblank = sun4i_drv_disable_vblank, }; -static void sun4i_remove_framebuffers (void ) -{ -struct apertures_struct *ap; - - ap =alloc_apertures (1 ); -if (!ap) -return ; - -/* The framebuffer can be located anywhere in RAM */ - ap->ranges[0 ].base =0 ; - ap->ranges[0 ].size = ~0 ; - -remove_conflicting_framebuffers (ap,"sun4i-drm-fb" , false); -kfree (ap); -} -static int sun4i_drv_bind (struct device *dev) {struct drm_device *drm;struct sun4i_drv *drv;int ret; + ret =sysfb_evict_conflicts_firmware (); +if (ret <0 ) +return ret; + drm =drm_dev_alloc (&sun4i_drv_driver, dev);if (!drm)return -ENOMEM ;
@@ -156,9 +145,6 @@ static int sun4i_drv_bind(struct device *dev) } drm->irq_enabled = true; -/* Remove early framebuffers (ie. simplefb) */ -sun4i_remove_framebuffers (); -/* Create our framebuffer */ drv->fbdev =sun4i_framebuffer_init (drm);if (IS_ERR (drv->fbdev)) {
drivers/gpu/drm/vc4/vc4_drv.c +5 -20
@@ -15,6 +15,7 @@#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/sysfb.h> #include "drm_fb_cma_helper.h" #include "uapi/drm/vc4_drm.h"
@@ -200,24 +201,6 @@ static void vc4_match_add_drivers(struct device *dev, } } -static void vc4_kick_out_firmware_fb (void ) -{ -struct apertures_struct *ap; - - ap =alloc_apertures (1 ); -if (!ap) -return ; - -/* Since VC4 is a UMA device, the simplefb node may have been -* located anywhere in memory. -*/ - ap->ranges[0 ].base =0 ; - ap->ranges[0 ].size = ~0 ; - -remove_conflicting_framebuffers (ap,"vc4drmfb" , false); -kfree (ap); -} -static int vc4_drm_bind (struct device *dev) {struct platform_device *pdev =to_platform_device (dev);
@@ -225,6 +208,10 @@ static int vc4_drm_bind(struct device *dev)struct vc4_dev *vc4;int ret =0 ; + ret =sysfb_evict_conflicts_firmware (); +if (ret <0 ) +return ret; + dev->coherent_dma_mask =DMA_BIT_MASK (32 ); vc4 =devm_kzalloc (dev,sizeof (*vc4),GFP_KERNEL );
@@ -248,8 +235,6 @@ static int vc4_drm_bind(struct device *dev)if (ret) goto gem_destroy; -vc4_kick_out_firmware_fb (); - ret =drm_dev_register (drm,0 );if (ret <0 ) goto unbind_all;
drivers/gpu/drm/virtio/virtgpu_drm_bus.c +2 -22
@@ -24,29 +24,10 @@*/ #include <linux/pci.h> +#include <linux/sysfb.h> #include "virtgpu_drv.h" -static void virtio_pci_kick_out_firmware_fb (struct pci_dev *pci_dev) -{ -struct apertures_struct *ap; -bool primary; - - ap =alloc_apertures (1 ); -if (!ap) -return ; - - ap->ranges[0 ].base =pci_resource_start (pci_dev,0 ); - ap->ranges[0 ].size =pci_resource_len (pci_dev,0 ); - - primary = pci_dev->resource[PCI_ROM_RESOURCE ].flags - &IORESOURCE_ROM_SHADOW ; - -remove_conflicting_framebuffers (ap,"virtiodrmfb" , primary); - -kfree (ap); -} -int drm_virtio_init (struct drm_driver *driver,struct virtio_device *vdev) {struct drm_device *dev;
@@ -65,8 +46,7 @@ int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev)DRM_INFO ("pci: %s detected\n" , vga ?"virtio-vga" :"virtio-gpu-pci" ); dev->pdev = pdev; -if (vga) -virtio_pci_kick_out_firmware_fb (pdev); +sysfb_evict_conflicts_pci (pdev); } ret =drm_dev_register (dev,0 );
Signature · 6 lines
2.9.3 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 5/7] drm: switch to sysfb_evict_conflicts()
Den 02.09.2016 10:22, skrev David Herrmann:
Quoted 7 lines
Switch over all DRM drivers to use the new
sysfb_evict_conflicts()infrastructure. The only non-trivial conversion is i915, since it does not make use of the generic PCI resources, but assembles the apertures via intel ggtt queries.Signed-off-by David Herrmann <[email protected]>---
This doesn't apply now with Daniel's wrapper added:drm_fb_helper_remove_conflicting_framebuffers().
Noralf.
Quoted 562 lines
drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 24 +---------- drivers/gpu/drm/bochs/bochs_drv.c | 19 +-------- drivers/gpu/drm/i915/i915_drv.c | 73 ++++++-------------------------- drivers/gpu/drm/mgag200/mgag200_drv.c | 27 +++--------- drivers/gpu/drm/mgag200/mgag200_main.c | 9 ---- drivers/gpu/drm/nouveau/nouveau_drm.c | 33 +++------------ drivers/gpu/drm/radeon/radeon_drv.c | 24 +---------- drivers/gpu/drm/sun4i/sun4i_drv.c | 24 +++-------- drivers/gpu/drm/vc4/vc4_drv.c | 25 +++-------- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 24 +---------- 11 files changed, 44 insertions(+), 239 deletions(-)drivers/gpu/drm/Kconfig +1
-0@@ -12,6 +12,7 @@ menuconfig DRM select I2C select I2C_ALGOBIT select DMA_SHARED_BUFFER + select SYSFB help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to selectdrivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +2
-22@@ -38,6 +38,7 @@#include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/sysfb.h> #include <linux/vga_switcheroo.h> #include "drm_crtc_helper.h" @@ -326,27 +327,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);static struct drm_driver kms_driver; -static int amdgpu_kick_out_firmware_fb (struct pci_dev *pdev) -{ -struct apertures_struct *ap; -bool primary = false; - - ap =alloc_apertures (1 ); -if (!ap) -return -ENOMEM ; - - ap->ranges[0 ].base =pci_resource_start (pdev,0 ); - ap->ranges[0 ].size =pci_resource_len (pdev,0 ); - -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; -#endif -remove_conflicting_framebuffers (ap,"amdgpudrmfb" , primary); -kfree (ap); - -return 0 ; -} -static int amdgpu_pci_probe (struct pci_dev *pdev,const struct pci_device_id *ent) {@@ -368,7 +348,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,return ret;/* Get rid of things like offb */ - ret =amdgpu_kick_out_firmware_fb (pdev); + ret =sysfb_evict_conflicts_pci (pdev);if (ret)return ret;drivers/gpu/drm/bochs/bochs_drv.c +2
-17@@ -8,6 +8,7 @@#include <linux/mm.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/sysfb.h> #include "bochs.h" @@ -143,28 +144,12 @@ static const struct dev_pm_ops bochs_pm_ops = {/* ---------------------------------------------------------------------- */ /* pci interface */ -static int bochs_kick_out_firmware_fb (struct pci_dev *pdev) -{ -struct apertures_struct *ap; - - ap =alloc_apertures (1 ); -if (!ap) -return -ENOMEM ; - - ap->ranges[0 ].base =pci_resource_start (pdev,0 ); - ap->ranges[0 ].size =pci_resource_len (pdev,0 ); -remove_conflicting_framebuffers (ap,"bochsdrmfb" , false); -kfree (ap); - -return 0 ; -} -static int bochs_pci_probe (struct pci_dev *pdev,const struct pci_device_id *ent) {int ret; - ret =bochs_kick_out_firmware_fb (pdev); + ret =sysfb_evict_conflicts_pci (pdev);if (ret)return ret;drivers/gpu/drm/i915/i915_drv.c +14
-59@@ -36,6 +36,7 @@#include <linux/pm_runtime.h> #include <linux/pnp.h> #include <linux/slab.h> +#include <linux/sysfb.h> #include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> #include <linux/vt.h> @@ -687,70 +688,32 @@ out:return ret; } -#if IS_ENABLED (CONFIG_FB )static int i915_kick_out_firmware_fb (struct drm_i915_private *dev_priv) { -struct apertures_struct *ap; +struct sysfb_evict_ctx ctx = {};struct pci_dev *pdev = dev_priv->drm.pdev;struct i915_ggtt *ggtt = &dev_priv->ggtt; -bool primary;int ret; - ap =alloc_apertures (1 ); -if (!ap) -return -ENOMEM ; - - ap->ranges[0 ].base = ggtt->mappable_base; - ap->ranges[0 ].size = ggtt->mappable_end; - - primary = - pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; - - ret =remove_conflicting_framebuffers (ap,"inteldrmfb" , primary); - -kfree (ap); - -return ret; -} -#else -static int i915_kick_out_firmware_fb (struct drm_i915_private *dev_priv) -{ -return 0 ; -} -#endif + ctx.flags =SYSFB_EVICT_PLATFORM | +SYSFB_EVICT_FBDEV | +SYSFB_EVICT_VGACON ; -#if !defined(CONFIG_VGA_CONSOLE ) -static int i915_kick_out_vgacon (struct drm_i915_private *dev_priv) -{ -return 0 ; -} -#elif !defined(CONFIG_DUMMY_CONSOLE ) -static int i915_kick_out_vgacon (struct drm_i915_private *dev_priv) -{ -return -ENODEV ; -} -#else -static int i915_kick_out_vgacon (struct drm_i915_private *dev_priv) -{ -int ret =0 ; + ctx.ap =alloc_apertures (1 ); +if (!ctx.ap) +return -ENOMEM ; -DRM_INFO ("Replacing VGA console driver\n" ); + ctx.ap->ranges[0 ].base = ggtt->mappable_base; + ctx.ap->ranges[0 ].size = ggtt->mappable_end; -console_lock (); -if (con_is_bound (&vga_con)) - ret =do_take_over_console (&dummy_con,0 ,MAX_NR_CONSOLES -1 ,1 ); -if (ret ==0 ) { - ret =do_unregister_con_driver (&vga_con); +if (pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ) + ctx.flags |=SYSFB_EVICT_VBE ; -/* Ignore "already unregistered". */ -if (ret == -ENODEV ) - ret =0 ; - } -console_unlock (); + ret =sysfb_evict_conflicts (&ctx); +kfree (ctx.ap);return ret; } -#endif static void intel_init_dpio (struct drm_i915_private *dev_priv) {@@ -1032,20 +995,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) goto out_ggtt; } -/* WARNING: Apparently we must kick fbdev drivers before vgacon, -* otherwise the vga fbdev driver falls over. */ ret =i915_kick_out_firmware_fb (dev_priv);if (ret) {DRM_ERROR ("failed to remove conflicting framebuffer drivers\n" ); goto out_ggtt; } - ret =i915_kick_out_vgacon (dev_priv); -if (ret) { -DRM_ERROR ("failed to remove conflicting VGA console\n" ); - goto out_ggtt; - } -pci_set_master (dev->pdev);/* overlay on gen2 is broken and can't address above 1G */ drivers/gpu/drm/mgag200/mgag200_drv.c +6
-21@@ -10,6 +10,7 @@*/ #include <linux/module.h> #include <linux/console.h> +#include <linux/sysfb.h> #include <drm/drmP.h> #include "mgag200_drv.h" @@ -41,29 +42,13 @@ static const struct pci_device_id pciidlist[] = {MODULE_DEVICE_TABLE (pci, pciidlist); -static void mgag200_kick_out_firmware_fb (struct pci_dev *pdev) -{ -struct apertures_struct *ap; -bool primary = false; - - ap =alloc_apertures (1 ); -if (!ap) -return ; - - ap->ranges[0 ].base =pci_resource_start (pdev,0 ); - ap->ranges[0 ].size =pci_resource_len (pdev,0 ); - -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; -#endif -remove_conflicting_framebuffers (ap,"mgag200drmfb" , primary); -kfree (ap); -} - -static int mga_pci_probe (struct pci_dev *pdev,const struct pci_device_id *ent) { -mgag200_kick_out_firmware_fb (pdev); +int ret; + + ret =sysfb_evict_conflicts_pci (pdev); +if (ret <0 ) +return ret;return drm_get_pci_dev (pdev, ent, &driver); }drivers/gpu/drm/mgag200/mgag200_main.c +0
-9@@ -124,20 +124,11 @@ static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem)static int mga_vram_init (struct mga_device *mdev) {void __iomem *mem; -struct apertures_struct *aper =alloc_apertures (1 ); -if (!aper) -return -ENOMEM ;/* BAR 0 is VRAM */ mdev->mc.vram_base =pci_resource_start (mdev->dev->pdev,0 ); mdev->mc.vram_window =pci_resource_len (mdev->dev->pdev,0 ); - aper->ranges[0 ].base = mdev->mc.vram_base; - aper->ranges[0 ].size = mdev->mc.vram_window; - -remove_conflicting_framebuffers (aper,"mgafb" , true); -kfree (aper); -if (!devm_request_mem_region (mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window,"mgadrmfb_vram" )) {DRM_ERROR ("can't reserve VRAM\n" );drivers/gpu/drm/nouveau/nouveau_drm.c +5
-28@@ -27,6 +27,7 @@#include <linux/module.h> #include <linux/pci.h> #include <linux/pm_runtime.h> +#include <linux/sysfb.h> #include <linux/vga_switcheroo.h> #include "drmP.h" @@ -310,8 +311,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent) {struct nvkm_device *device; -struct apertures_struct *aper; -bool boot = false;int ret;if (vga_switcheroo_client_probe_defer (pdev))@@ -326,34 +325,12 @@ static int nouveau_drm_probe(struct pci_dev *pdev,nvkm_device_del (&device); -/* Remove conflicting drivers (vesafb, efifb etc). */ - aper =alloc_apertures (3 ); -if (!aper) -return -ENOMEM ; - - aper->ranges[0 ].base =pci_resource_start (pdev,1 ); - aper->ranges[0 ].size =pci_resource_len (pdev,1 ); - aper->count =1 ; - -if (pci_resource_len (pdev,2 )) { - aper->ranges[aper->count].base =pci_resource_start (pdev,2 ); - aper->ranges[aper->count].size =pci_resource_len (pdev,2 ); - aper->count++; - } - -if (pci_resource_len (pdev,3 )) { - aper->ranges[aper->count].base =pci_resource_start (pdev,3 ); - aper->ranges[aper->count].size =pci_resource_len (pdev,3 ); - aper->count++; +if (nouveau_modeset !=2 ) { + ret =sysfb_evict_conflicts_pci (pdev); +if (ret <0 ) +return ret; } -#ifdef CONFIG_X86 - boot = pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; -#endif -if (nouveau_modeset !=2 ) -remove_conflicting_framebuffers (aper,"nouveaufb" , boot); -kfree (aper); - ret =nvkm_device_pci_new (pdev, nouveau_config, nouveau_debug, true, true, ~0ULL , &device);if (ret)drivers/gpu/drm/radeon/radeon_drv.c +2
-22@@ -37,6 +37,7 @@#include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/sysfb.h> #include <linux/vga_switcheroo.h> #include <drm/drm_gem.h> @@ -309,27 +310,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);static struct drm_driver kms_driver; -static int radeon_kick_out_firmware_fb (struct pci_dev *pdev) -{ -struct apertures_struct *ap; -bool primary = false; - - ap =alloc_apertures (1 ); -if (!ap) -return -ENOMEM ; - - ap->ranges[0 ].base =pci_resource_start (pdev,0 ); - ap->ranges[0 ].size =pci_resource_len (pdev,0 ); - -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE ].flags &IORESOURCE_ROM_SHADOW ; -#endif -remove_conflicting_framebuffers (ap,"radeondrmfb" , primary); -kfree (ap); - -return 0 ; -} -static int radeon_pci_probe (struct pci_dev *pdev,const struct pci_device_id *ent) {@@ -347,7 +327,7 @@ static int radeon_pci_probe(struct pci_dev *pdev,return -EPROBE_DEFER ;/* Get rid of things like offb */ - ret =radeon_kick_out_firmware_fb (pdev); + ret =sysfb_evict_conflicts_pci (pdev);if (ret)return ret;drivers/gpu/drm/sun4i/sun4i_drv.c +5
-19@@ -12,6 +12,7 @@#include <linux/component.h> #include <linux/of_graph.h> +#include <linux/sysfb.h> #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> @@ -97,28 +98,16 @@ static struct drm_driver sun4i_drv_driver = { .disable_vblank = sun4i_drv_disable_vblank, }; -static void sun4i_remove_framebuffers (void ) -{ -struct apertures_struct *ap; - - ap =alloc_apertures (1 ); -if (!ap) -return ; - -/* The framebuffer can be located anywhere in RAM */ - ap->ranges[0 ].base =0 ; - ap->ranges[0 ].size = ~0 ; - -remove_conflicting_framebuffers (ap,"sun4i-drm-fb" , false); -kfree (ap); -} -static int sun4i_drv_bind (struct device *dev) {struct drm_device *drm;struct sun4i_drv *drv;int ret; + ret =sysfb_evict_conflicts_firmware (); +if (ret <0 ) +return ret; + drm =drm_dev_alloc (&sun4i_drv_driver, dev);if (!drm)return -ENOMEM ;@@ -156,9 +145,6 @@ static int sun4i_drv_bind(struct device *dev) } drm->irq_enabled = true; -/* Remove early framebuffers (ie. simplefb) */ -sun4i_remove_framebuffers (); -/* Create our framebuffer */ drv->fbdev =sun4i_framebuffer_init (drm);if (IS_ERR (drv->fbdev)) {drivers/gpu/drm/vc4/vc4_drv.c +5
-20@@ -15,6 +15,7 @@#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/sysfb.h> #include "drm_fb_cma_helper.h" #include "uapi/drm/vc4_drm.h" @@ -200,24 +201,6 @@ static void vc4_match_add_drivers(struct device *dev, } } -static void vc4_kick_out_firmware_fb (void ) -{ -struct apertures_struct *ap; - - ap =alloc_apertures (1 ); -if (!ap) -return ; - -/* Since VC4 is a UMA device, the simplefb node may have been -* located anywhere in memory. -*/ - ap->ranges[0 ].base =0 ; - ap->ranges[0 ].size = ~0 ; - -remove_conflicting_framebuffers (ap,"vc4drmfb" , false); -kfree (ap); -} -static int vc4_drm_bind (struct device *dev) {struct platform_device *pdev =to_platform_device (dev);@@ -225,6 +208,10 @@ static int vc4_drm_bind(struct device *dev)struct vc4_dev *vc4;int ret =0 ; + ret =sysfb_evict_conflicts_firmware (); +if (ret <0 ) +return ret; + dev->coherent_dma_mask =DMA_BIT_MASK (32 ); vc4 =devm_kzalloc (dev,sizeof (*vc4),GFP_KERNEL );@@ -248,8 +235,6 @@ static int vc4_drm_bind(struct device *dev)if (ret) goto gem_destroy; -vc4_kick_out_firmware_fb (); - ret =drm_dev_register (drm,0 );if (ret <0 ) goto unbind_all;drivers/gpu/drm/virtio/virtgpu_drm_bus.c +1
-20@@ -24,29 +24,10 @@*/ #include <linux/pci.h> +#include <linux/sysfb.h> #include "virtgpu_drv.h" -static void virtio_pci_kick_out_firmware_fb (struct pci_dev *pci_dev) -{ -struct apertures_struct *ap; -bool primary; - - ap =alloc_apertures (1 ); -if (!ap) -return ; - - ap->ranges[0 ].base =pci_resource_start (pci_dev,0 ); - ap->ranges[0 ].size =pci_resource_len (pci_dev,0 ); - - primary = pci_dev->resource[PCI_ROM_RESOURCE ].flags - &IORESOURCE_ROM_SHADOW ; - -remove_conflicting_framebuffers (ap,"virtiodrmfb" , primary); - -kfree (ap); -} -int drm_virtio_init (struct drm_driver *driver,struct virtio_device *vdev) {struct drm_device *dev;
drivers/gpu/drm/virtio/virtgpu_drm_bus.c int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev) · line 52
Quoted 9 lines
drivers/gpu/drm/virtio/virtgpu_drm_bus.c +1
-2@@ -65,8 +46,7 @@ int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev)DRM_INFO ("pci: %s detected\n" , vga ?"virtio-vga" :"virtio-gpu-pci" ); dev->pdev = pdev; -if (vga) -virtio_pci_kick_out_firmware_fb (pdev); +sysfb_evict_conflicts_pci (pdev); } ret =drm_dev_register (dev,0 );
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v5 6/7 drm: add SimpleDRM driver
In reply to David HerrmannThe SimpleDRM driver binds to simple-framebuffer devices and provides a DRM/KMS API. It provides only a single CRTC+encoder+connector combination plus one initial mode.
Userspace can create dumb-buffers which can be blit into the real framebuffer similar to UDL. No access to the real framebuffer is allowed (compared to earlier version of this driver) to avoid security issues. Furthermore, this way we can support arbitrary modes as long as we have a conversion-helper.
--- MAINTAINERS | 6 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/simpledrm/Kconfig | 19 ++ drivers/gpu/drm/simpledrm/Makefile | 8 + drivers/gpu/drm/simpledrm/simpledrm.h | 83 +++++ drivers/gpu/drm/simpledrm/simpledrm_damage.c | 194 +++++++++++ drivers/gpu/drm/simpledrm/simpledrm_drv.c | 464 +++++++++++++++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_gem.c | 109 +++++++ drivers/gpu/drm/simpledrm/simpledrm_kms.c | 263 +++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_of.c | 265 +++++++++++++++ 11 files changed, 1414 insertions(+) create mode 100644 drivers/gpu/drm/simpledrm/Kconfig create mode 100644 drivers/gpu/drm/simpledrm/Makefile create mode 100644 drivers/gpu/drm/simpledrm/simpledrm.h create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_damage.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_drv.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_gem.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_kms.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_of.c
MAINTAINERS +6 -0
@@ -4140,6 +4140,12 @@ S: Orphan / Obsolete F: drivers/gpu/drm/savage/ F: include/uapi/drm/savage_drm.h +DRM DRIVER FOR SIMPLE FRAMEBUFFER DEVICES +M: David Herrmann <[email protected]> +L: [email protected] +S: Maintained +F: drivers/gpu/drm/simpledrm/ + DRM DRIVER FOR SIS VIDEO CARDS S: Orphan / Obsolete F: drivers/gpu/drm/sis/
drivers/gpu/drm/Kconfig +2 -0
@@ -291,3 +291,5 @@ source "drivers/gpu/drm/arc/Kconfig" source "drivers/gpu/drm/hisilicon/Kconfig" source "drivers/gpu/drm/mediatek/Kconfig" + +source "drivers/gpu/drm/simpledrm/Kconfig"
drivers/gpu/drm/Makefile +1 -0
@@ -83,3 +83,4 @@ obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/ obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/ obj-$(CONFIG_DRM_ARCPGU)+= arc/ obj-y += hisilicon/ +obj-y += simpledrm/
drivers/gpu/drm/simpledrm/Kconfig new file +19 -0
@@ -0,0 +1,19 @@ +config DRM_SIMPLEDRM + tristate "Simple firmware framebuffer DRM driver" + depends on DRM + select DRM_KMS_HELPER + help + SimpleDRM can run on all systems with pre-initialized graphics + hardware. It uses a framebuffer that was initialized during + firmware boot. No page-flipping, modesetting or other advanced + features are available. However, other DRM drivers can be loaded + later and take over from SimpleDRM if they provide real hardware + support. + + SimpleDRM supports "simple-framebuffer" DeviceTree objects and + compatible platform framebuffers. + + If unsure, say Y. + + To compile this driver as a module, choose M here: the + module will be called simpledrm.
drivers/gpu/drm/simpledrm/Makefile new file +8 -0
@@ -0,0 +1,8 @@ +simpledrm-y := \ + simpledrm_damage.o \ + simpledrm_drv.o \ + simpledrm_gem.o \ + simpledrm_kms.o \ + simpledrm_of.o + +obj-$(CONFIG_DRM_SIMPLEDRM) := simpledrm.o
drivers/gpu/drm/simpledrm/simpledrm.h new file +83 -0
83 lines not on this page · raw message
drivers/gpu/drm/simpledrm/simpledrm_damage.c new file +194 -0
194 lines not on this page · raw message
drivers/gpu/drm/simpledrm/simpledrm_drv.c new file +464 -0
464 lines not on this page · raw message
drivers/gpu/drm/simpledrm/simpledrm_gem.c new file +109 -0
109 lines not on this page · raw message
drivers/gpu/drm/simpledrm/simpledrm_kms.c new file +263 -0
263 lines not on this page · raw message
drivers/gpu/drm/simpledrm/simpledrm_of.c new file +265 -0
265 lines not on this page · raw message
Signature · 6 lines
2.9.3 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 6/7] drm: add SimpleDRM driver
Quoted 494 lines · David Herrmann
The SimpleDRM driver binds to simple-framebuffer devices and provides a DRM/KMS API. It provides only a single CRTC+encoder+connector combination plus one initial mode.
Userspace can create dumb-buffers which can be blit into the real framebuffer similar to UDL. No access to the real framebuffer is allowed (compared to earlier version of this driver) to avoid security issues. Furthermore, this way we can support arbitrary modes as long as we have a conversion-helper.
Signed-off-by David Herrmann <[email protected]>--- MAINTAINERS | 6 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/simpledrm/Kconfig | 19 ++ drivers/gpu/drm/simpledrm/Makefile | 8 + drivers/gpu/drm/simpledrm/simpledrm.h | 83 +++++ drivers/gpu/drm/simpledrm/simpledrm_damage.c | 194 +++++++++++ drivers/gpu/drm/simpledrm/simpledrm_drv.c | 464 +++++++++++++++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_gem.c | 109 +++++++ drivers/gpu/drm/simpledrm/simpledrm_kms.c | 263 +++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_of.c | 265 +++++++++++++++ 11 files changed, 1414 insertions(+) create mode 100644 drivers/gpu/drm/simpledrm/Kconfig create mode 100644 drivers/gpu/drm/simpledrm/Makefile create mode 100644 drivers/gpu/drm/simpledrm/simpledrm.h create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_damage.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_drv.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_gem.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_kms.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_of.cMAINTAINERS +6
-0@@ -4140,6 +4140,12 @@ S: Orphan / Obsolete F: drivers/gpu/drm/savage/ F: include/uapi/drm/savage_drm.h +DRM DRIVER FOR SIMPLE FRAMEBUFFER DEVICES +M: David Herrmann <[email protected]> +L: [email protected] +S: Maintained +F: drivers/gpu/drm/simpledrm/ + DRM DRIVER FOR SIS VIDEO CARDS S: Orphan / Obsolete F: drivers/gpu/drm/sis/drivers/gpu/drm/Kconfig +2
-0@@ -291,3 +291,5 @@ source "drivers/gpu/drm/arc/Kconfig" source "drivers/gpu/drm/hisilicon/Kconfig" source "drivers/gpu/drm/mediatek/Kconfig" + +source "drivers/gpu/drm/simpledrm/Kconfig"drivers/gpu/drm/Makefile +1
-0@@ -83,3 +83,4 @@ obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/ obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/ obj-$(CONFIG_DRM_ARCPGU)+= arc/ obj-y += hisilicon/ +obj-y += simpledrm/drivers/gpu/drm/simpledrm/Kconfig new file +19
-0@@ -0,0 +1,19 @@ +config DRM_SIMPLEDRM + tristate "Simple firmware framebuffer DRM driver" + depends on DRM + select DRM_KMS_HELPER + help + SimpleDRM can run on all systems with pre-initialized graphics + hardware. It uses a framebuffer that was initialized during + firmware boot. No page-flipping, modesetting or other advanced + features are available. However, other DRM drivers can be loaded + later and take over from SimpleDRM if they provide real hardware + support. + + SimpleDRM supports "simple-framebuffer" DeviceTree objects and + compatible platform framebuffers. + + If unsure, say Y. + + To compile this driver as a module, choose M here: the + module will be called simpledrm.drivers/gpu/drm/simpledrm/Makefile new file +8
-0@@ -0,0 +1,8 @@ +simpledrm-y := \ + simpledrm_damage.o \ + simpledrm_drv.o \ + simpledrm_gem.o \ + simpledrm_kms.o \ + simpledrm_of.o + +obj-$(CONFIG_DRM_SIMPLEDRM) := simpledrm.odrivers/gpu/drm/simpledrm/simpledrm.h new file +83
-0@@ -0,0 +1,83 @@ +#ifndef __SDRM_SIMPLEDRM_H +#define __SDRM_SIMPLEDRM_H + +/* +* Copyright (C) 2012-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include <drm/drm_gem.h> +#include <drm/drm_simple_kms_helper.h> +#include <linux/atomic.h> +#include <linux/kernel.h> +#include <linux/mutex.h> + +struct clk ; +struct regulator ; +struct simplefb_format ; + +struct sdrm_hw { +struct mutex lock; +u32 width; +u32 height; +u32 stride; +u32 bpp; +u32 format; +unsigned long base; +unsigned long size; +void *map; +}; + +struct sdrm_bo { +struct drm_gem_object base; +struct page **pages; +void *vmapping; +}; + +struct sdrm_fb { +struct drm_framebuffer base; +struct sdrm_bo *bo; +}; + +struct sdrm_device { +atomic_t n_used; +struct drm_device *ddev; +struct sdrm_hw *hw; + +size_t n_clks; +size_t n_regulators; +struct clk **clks; +struct regulator **regulators; + +struct drm_simple_display_pipe pipe; +struct drm_connector conn; +}; + +void sdrm_of_bootstrap (void ); +int sdrm_of_bind (struct sdrm_device *sdrm); +void sdrm_of_unbind (struct sdrm_device *sdrm); + +int sdrm_kms_bind (struct sdrm_device *sdrm); +void sdrm_kms_unbind (struct sdrm_device *sdrm); + +void sdrm_dirty (struct sdrm_fb *fb,u32 x,u32 y,u32 width,u32 height); + +struct sdrm_bo *sdrm_bo_new (struct drm_device *ddev,size_t size); +void sdrm_bo_free (struct drm_gem_object *obj); +int sdrm_bo_vmap (struct sdrm_bo *bo); + +int sdrm_dumb_create (struct drm_file *dfile, +struct drm_device *ddev, +struct drm_mode_create_dumb *arg); +int sdrm_dumb_map_offset (struct drm_file *dfile, +struct drm_device *ddev, +uint32_t handle, +uint64_t *offset); + +#endif /* __SDRM_SIMPLEDRM_H */ drivers/gpu/drm/simpledrm/simpledrm_damage.c new file +194
-0@@ -0,0 +1,194 @@ +/* +* Copyright (C) 2012-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <asm/unaligned.h> +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include <linux/kernel.h> +#include "simpledrm.h" + +static inline void sdrm_put (u8 *dst,u32 four_cc,u16 r,u16 g,u16 b) +{ +switch (four_cc) { +case DRM_FORMAT_RGB565 : + r >>=11 ; + g >>=10 ; + b >>=11 ; +put_unaligned ((u16)((r <<11 ) | (g <<5 ) | b), (u16 *)dst); +break ; +case DRM_FORMAT_XRGB1555 : +case DRM_FORMAT_ARGB1555 : + r >>=11 ; + g >>=11 ; + b >>=11 ; +put_unaligned ((u16)((r <<10 ) | (g <<5 ) | b), (u16 *)dst); +break ; +case DRM_FORMAT_RGB888 : + r >>=8 ; + g >>=8 ; + b >>=8 ; +#ifdef __LITTLE_ENDIAN + dst[2 ] = r; + dst[1 ] = g; + dst[0 ] = b; +#elif defined(__BIG_ENDIAN) + dst[0 ] = r; + dst[1 ] = g; + dst[2 ] = b; +#endif +break ; +case DRM_FORMAT_XRGB8888 : +case DRM_FORMAT_ARGB8888 : + r >>=8 ; + g >>=8 ; + b >>=8 ; +put_unaligned ((u32)((r <<16 ) | (g <<8 ) | b), (u32 *)dst); +break ; +case DRM_FORMAT_ABGR8888 : + r >>=8 ; + g >>=8 ; + b >>=8 ; +put_unaligned ((u32)((b <<16 ) | (g <<8 ) | r), (u32 *)dst); +break ; +case DRM_FORMAT_XRGB2101010 : +case DRM_FORMAT_ARGB2101010 : + r >>=4 ; + g >>=4 ; + b >>=4 ; +put_unaligned ((u32)((r <<20 ) | (g <<10 ) | b), (u32 *)dst); +break ; + } +} + +static void sdrm_blit_from_xrgb8888 (const u8 *src, +u32 src_stride, +u32 src_bpp, +u8 *dst, +u32 dst_stride, +u32 dst_bpp, +u32 dst_four_cc, +u32 width, +u32 height) +{ +u32 val, i; + +while (height--) { +for (i =0 ; i < width; ++i) { + val =get_unaligned ((const u32 *)&src[i * src_bpp]); +sdrm_put (&dst[i * dst_bpp], dst_four_cc, + (val &0x00ff0000U ) >>8 , + (val &0x0000ff00U ), + (val &0x000000ffU ) <<8 ); + } + + src += src_stride; + dst += dst_stride; + } +} + +static void sdrm_blit_from_rgb565 (const u8 *src, +u32 src_stride, +u32 src_bpp, +u8 *dst, +u32 dst_stride, +u32 dst_bpp, +u32 dst_four_cc, +u32 width, +u32 height) +{ +u32 val, i; + +while (height--) { +for (i =0 ; i < width; ++i) { + val =get_unaligned ((const u16 *)&src[i * src_bpp]); +sdrm_put (&dst[i * dst_bpp], dst_four_cc, + (val &0xf800 ), + (val &0x07e0 ) <<5 , + (val &0x001f ) <<11 ); + } + + src += src_stride; + dst += dst_stride; + } +} + +static void sdrm_blit_lines (const u8 *src, +u32 src_stride, +u8 *dst, +u32 dst_stride, +u32 bpp, +u32 width, +u32 height) +{ +u32 len; + + len = width * bpp; + +while (height--) { +memcpy (dst, src, len); + src += src_stride; + dst += dst_stride; + } +} + +static void sdrm_blit (struct sdrm_hw *hw, +struct sdrm_fb *fb, +u32 x, +u32 y, +u32 width, +u32 height) +{ +u32 src_bpp, dst_bpp; +u8 *src, *dst; + + src = fb->bo->vmapping; + src_bpp =DIV_ROUND_UP (fb->base.bits_per_pixel,8 ); + src += fb->base.offsets[0 ] + y * fb->base.pitches[0 ] + x * src_bpp; + + dst = hw->map; + dst_bpp =DIV_ROUND_UP (hw->bpp,8 ); + dst += y * hw->stride + x * dst_bpp; + +if (fb->base.pixel_format == hw->format) { +/* if formats are identical, do a line-by-line copy.. */ +sdrm_blit_lines (src, fb->base.pitches[0 ], + dst, hw->stride, src_bpp, width, height); + }else { +/* ..otherwise call slow blit-function */ +switch (fb->base.pixel_format) { +case DRM_FORMAT_ARGB8888 : +case DRM_FORMAT_XRGB8888 : +sdrm_blit_from_xrgb8888 (src, fb->base.pitches[0 ], + src_bpp, dst, hw->stride, + dst_bpp, hw->format, + width, height); +break ; +case DRM_FORMAT_RGB565 : +sdrm_blit_from_rgb565 (src, fb->base.pitches[0 ], + src_bpp, dst, hw->stride, + dst_bpp, hw->format, + width, height); +break ; + } + } +} + +void sdrm_dirty (struct sdrm_fb *fb,u32 x,u32 y,u32 width,u32 height) +{ +struct sdrm_device *sdrm = fb->base.dev->dev_private; + +if (WARN_ON (!fb->bo->vmapping)) +return ; + +mutex_lock (&sdrm->hw->lock); +if (sdrm->hw->map) +sdrm_blit (sdrm->hw, fb, x, y, width, height); +mutex_unlock (&sdrm->hw->lock); +}drivers/gpu/drm/simpledrm/simpledrm_drv.c new file +91
-0@@ -0,0 +1,464 @@ +/* +* Copyright (C) 2012-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <drm/drmP.h> +#include <linux/atomic.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_data/simplefb.h> +#include <linux/string.h> +#include "simpledrm.h" + +static struct drm_driver sdrm_drm_driver; +static DEFINE_MUTEX (sdrm_lock); + +static int sdrm_hw_identify (struct platform_device *pdev, +struct simplefb_platform_data *modep, +struct simplefb_format *formatp, +struct resource **memp, +u32 *bppp) +{ +static const struct simplefb_format valid_formats[] =SIMPLEFB_FORMATS ; +struct simplefb_platform_data pm = {}, *mode = pdev->dev.platform_data; +struct device_node *np = pdev->dev.of_node; +const struct simplefb_format *format =NULL ; +struct resource *mem; +unsigned int depth; +int r, bpp; +size_t i; + +if (!mode) { +if (!np) +return -ENODEV ; + + mode = ± + + r =of_property_read_u32 (np,"width" , &mode->width); +if (r >=0 ) + r =of_property_read_u32 (np,"height" , &mode->height); +if (r >=0 ) + r =of_property_read_u32 (np,"stride" , &mode->stride); +if (r >=0 ) + r =of_property_read_string (np,"format" , + &mode->format); +if (r <0 ) +return r; + } + + mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!mem) +return -ENODEV ; + +for (i =0 ; i <ARRAY_SIZE (valid_formats); ++i) { +if (!strcmp (mode->format, valid_formats[i].name)) { + format = &valid_formats[i]; +break ; + } + } + +if (!format) +return -ENODEV ; + +switch (format->fourcc) { +case DRM_FORMAT_RGB565 : +case DRM_FORMAT_XRGB1555 : +case DRM_FORMAT_ARGB1555 : +case DRM_FORMAT_RGB888 : +case DRM_FORMAT_XRGB8888 : +case DRM_FORMAT_ARGB8888 : +case DRM_FORMAT_ABGR8888 : +case DRM_FORMAT_XRGB2101010 : +case DRM_FORMAT_ARGB2101010 : +/* +* You must adjust sdrm_put() whenever you add a new format +* here, otherwise, blitting operations will not work. +* Furthermore, include/linux/platform_data/simplefb.h needs +* to be adjusted so the platform-device actually allows this +* format. +*/ +break ;
drivers/gpu/drm/simpledrm/simpledrm_drv.c line 101
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c new file +10
-0+default : +return -ENODEV ; + } + +drm_fb_get_bpp_depth (format->fourcc, &depth, &bpp); +if (!bpp) +return -ENODEV ; +if (resource_size (mem) < mode->stride * mode->height) +return -ENODEV ; +if ((bpp +7 ) /8 * mode->width > mode->stride)
DIV_ROUND_UP?
Quoted 439 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c new file +363
-0+return -ENODEV ; + + *modep = *mode; + *formatp = *format; + *memp = mem; + *bppp = bpp; +return 0 ; +} + +static struct sdrm_hw *sdrm_hw_new (const struct simplefb_platform_data *mode, +const struct simplefb_format *format, +const struct resource *mem, +u32 bpp) +{ +struct sdrm_hw *hw; + + hw =kzalloc (sizeof (*hw),GFP_KERNEL ); +if (!hw) +return ERR_PTR (-ENOMEM ); + +mutex_init (&hw->lock); + hw->width = mode->width; + hw->height = mode->height; + hw->stride = mode->stride; + hw->bpp = bpp; + hw->format = format->fourcc; + hw->base = mem->start; + hw->size =resource_size (mem); + +return hw; +} + +static struct sdrm_hw *sdrm_hw_free (struct sdrm_hw *hw) +{ +if (!hw) +return NULL ; + +WARN_ON (hw->map); +mutex_destroy (&hw->lock); +kfree (hw); + +return NULL ; +} + +static int sdrm_hw_bind (struct sdrm_hw *hw) +{ +mutex_lock (&hw->lock); +if (!hw->map) + hw->map =ioremap_wc (hw->base, hw->size); +mutex_unlock (&hw->lock); + +return hw->map ?0 : -EIO ; +} + +static void sdrm_hw_unbind (struct sdrm_hw *hw) +{ +if (!hw) +return ; + +mutex_lock (&hw->lock); +if (hw->map) { +iounmap (hw->map); + hw->map =NULL ; + } +mutex_unlock (&hw->lock); +} + +static struct sdrm_device *sdrm_device_free (struct sdrm_device *sdrm) +{ +if (!sdrm) +return NULL ; + +WARN_ON (atomic_read (&sdrm->n_used) !=INT_MIN ); + sdrm->hw =sdrm_hw_free (sdrm->hw); +drm_dev_unref (sdrm->ddev); +kfree (sdrm); + +return NULL ; +} + +static struct sdrm_device *sdrm_device_new (struct platform_device *pdev, +struct sdrm_hw *hw) +{ +struct sdrm_device *sdrm; +int r; + + sdrm =kzalloc (sizeof (*sdrm),GFP_KERNEL ); +if (!sdrm) +return ERR_PTR (-ENOMEM ); + +atomic_set (&sdrm->n_used,INT_MIN ); + + sdrm->ddev =drm_dev_alloc (&sdrm_drm_driver, &pdev->dev); +if (!sdrm->ddev) { + r = -ENOMEM ; + goto error; + } + + sdrm->ddev->dev_private = sdrm; + sdrm->hw = hw; + +return sdrm; + +error: +sdrm_device_free (sdrm); +return ERR_PTR (r); +} + +static void sdrm_device_unbind (struct sdrm_device *sdrm) +{ +if (sdrm) { +sdrm_kms_unbind (sdrm); +sdrm_hw_unbind (sdrm->hw); +sdrm_of_unbind (sdrm); + } +} + +static int sdrm_device_bind (struct sdrm_device *sdrm) +{ +int r; + + r =sdrm_of_bind (sdrm); +if (r <0 ) + goto error; + + r =sdrm_hw_bind (sdrm->hw); +if (r <0 ) + goto error; + + r =sdrm_kms_bind (sdrm); +if (r <0 ) + goto error; + +return 0 ; + +error: +sdrm_device_unbind (sdrm); +return r; +} + +static int sdrm_device_acquire (struct sdrm_device *sdrm) +{ +return (sdrm &&atomic_inc_unless_negative (&sdrm->n_used)) + ?0 : -ENODEV ; +} + +static void sdrm_device_release (struct sdrm_device *sdrm) +{ +if (sdrm &&atomic_dec_return (&sdrm->n_used) ==INT_MIN ) { +sdrm_device_unbind (sdrm); +sdrm_device_free (sdrm); + } +} + +static int sdrm_fop_open (struct inode *inode,struct file *file) +{ +struct drm_device *ddev; +int r; + +mutex_lock (&sdrm_lock); + r =drm_open (inode, file); +if (r >=0 ) { + ddev = file->private_data; + r =sdrm_device_acquire (ddev->dev_private); +if (r <0 ) +drm_release (inode, file); + } +mutex_unlock (&sdrm_lock); + +return r; +} + +static int sdrm_fop_release (struct inode *inode,struct file *file) +{ +struct drm_file *dfile = file->private_data; +struct drm_device *ddev = dfile->minor->dev; +struct sdrm_device *sdrm = ddev->dev_private; +int res; + + res =drm_release (inode, file); +sdrm_device_release (sdrm); +return res; +} + +static int sdrm_fop_mmap (struct file *file,struct vm_area_struct *vma) +{ +struct drm_file *dfile = file->private_data; +struct drm_device *dev = dfile->minor->dev; +struct drm_gem_object *obj =NULL ; +struct drm_vma_offset_node *node; +int r; + +drm_vma_offset_lock_lookup (dev->vma_offset_manager); + node =drm_vma_offset_exact_lookup_locked (dev->vma_offset_manager, + vma->vm_pgoff, +vma_pages (vma)); +if (likely (node)) { + obj = container_of(node, struct drm_gem_object, vma_node); +if (!kref_get_unless_zero (&obj->refcount)) + obj =NULL ; + } +drm_vma_offset_unlock_lookup (dev->vma_offset_manager); + +if (!obj) +return -EINVAL ; + +if (!drm_vma_node_is_allowed (node, dfile)) { +drm_gem_object_unreference_unlocked (obj); +return -EACCES ; + } + +if (vma->vm_file) +fput (vma->vm_file); + vma->vm_file =get_file (obj->filp); + vma->vm_pgoff =0 ; + + r = obj->filp->f_op->mmap (obj->filp, vma); +drm_gem_object_unreference_unlocked (obj); +return r; +} + +static int sdrm_simplefb_probe (struct platform_device *pdev) +{ +struct simplefb_platform_data hw_mode; +struct simplefb_format hw_format; +struct sdrm_device *sdrm =NULL ; +struct sdrm_hw *hw =NULL ; +struct resource *hw_mem; +u32 hw_bpp; +int r; + + r =sdrm_hw_identify (pdev, &hw_mode, &hw_format, &hw_mem, &hw_bpp); +if (r <0 ) + goto error; + + hw =sdrm_hw_new (&hw_mode, &hw_format, hw_mem, hw_bpp); +if (IS_ERR (hw)) { + r =PTR_ERR (hw); + hw =NULL ; + goto error; + } + + sdrm =sdrm_device_new (pdev, hw); +if (IS_ERR (sdrm)) { + r =PTR_ERR (sdrm); + sdrm =NULL ; + goto error; + } + hw =NULL ; +platform_set_drvdata (pdev, sdrm); + + r =sdrm_device_bind (sdrm); +if (r <0 ) + goto error; + +/* mark device as enabled and acquire bus ref */ +WARN_ON (atomic_read (&sdrm->n_used) !=INT_MIN ); +atomic_set (&sdrm->n_used,1 ); + + r =drm_dev_register (sdrm->ddev,0 ); +if (r <0 ) { +/* mark device as disabled and drop bus ref */ +WARN_ON (atomic_add_return (INT_MIN , &sdrm->n_used) !=INT_MIN ); +sdrm_device_release (sdrm); +return r; + } + +dev_info (sdrm->ddev->dev,"initialized %s on minor %d\n" , + sdrm->ddev->driver->name, sdrm->ddev->primary->index); + +return 0 ; + +error: +sdrm_device_unbind (sdrm); +sdrm_device_free (sdrm); +sdrm_hw_free (hw); +return r; +} + +static int sdrm_simplefb_remove (struct platform_device *pdev) +{ +struct sdrm_device *sdrm =platform_get_drvdata (pdev); + +/* mark device as disabled */ +atomic_add (INT_MIN , &sdrm->n_used); +sdrm_hw_unbind (sdrm->hw); + +mutex_lock (&sdrm_lock); +drm_dev_unregister (sdrm->ddev); +sdrm_device_release (sdrm); +mutex_unlock (&sdrm_lock); + +return 0 ; +} + +static const struct file_operations sdrm_drm_fops = { + .owner =THIS_MODULE , + .open = sdrm_fop_open, + .release = sdrm_fop_release, + .mmap = sdrm_fop_mmap, + .poll = drm_poll, + .read = drm_read, + .unlocked_ioctl = drm_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, +#endif + .llseek = noop_llseek, +}; + +static struct drm_driver sdrm_drm_driver = { + .driver_features =DRIVER_GEM |DRIVER_MODESET |DRIVER_ATOMIC , + .fops = &sdrm_drm_fops, + + .gem_free_object = sdrm_bo_free, + + .dumb_create = sdrm_dumb_create, + .dumb_map_offset = sdrm_dumb_map_offset, + .dumb_destroy = drm_gem_dumb_destroy, + + .name ="simpledrm" , + .desc ="Simple firmware framebuffer DRM driver" , + .date ="20160901" , +}; + +static const struct of_device_id sdrm_simplefb_of_match[] = { + { .compatible ="simple-framebuffer" , }, + {}, +}; +MODULE_DEVICE_TABLE (of, sdrm_simplefb_of_match); + +static struct platform_driver sdrm_simplefb_driver = { + .probe = sdrm_simplefb_probe, + .remove = sdrm_simplefb_remove, + .driver = { + .name ="simple-framebuffer" , + .mod_name =KBUILD_MODNAME , + .owner =THIS_MODULE , + .of_match_table = sdrm_simplefb_of_match, + }, +}; + +static int __init sdrm_init (void ) +{ +int r; + + r =platform_driver_register (&sdrm_simplefb_driver); +if (r <0 ) +return r; + +sdrm_of_bootstrap (); +return 0 ; +} + +static void __exit sdrm_exit(void) +{ +platform_driver_unregister (&sdrm_simplefb_driver); +} + +module_init (sdrm_init); +module_exit (sdrm_exit); +MODULE_LICENSE ("GPL" ); +MODULE_DESCRIPTION ("Simple firmware framebuffer DRM driver" ); +MODULE_ALIAS ("platform:simple-framebuffer" );drivers/gpu/drm/simpledrm/simpledrm_gem.c new file +70
-0@@ -0,0 +1,109 @@ +/* +* Copyright (C) 2012-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <drm/drmP.h> +#include <drm/drm_gem.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include "simpledrm.h" + +struct sdrm_bo *sdrm_bo_new (struct drm_device *ddev,size_t size) +{ +struct sdrm_bo *bo; + +WARN_ON (!size || (size & ~PAGE_MASK ) !=0 ); + + bo =kzalloc (sizeof (*bo),GFP_KERNEL ); +if (!bo) +return NULL ; + +if (drm_gem_object_init (ddev, &bo->base, size)) { +kfree (bo); +return NULL ; + } + +return bo; +} + +void sdrm_bo_free (struct drm_gem_object *dobj) +{ + struct sdrm_bo *bo = container_of(dobj, struct sdrm_bo, base); + +if (bo->vmapping) +vunmap (bo->vmapping); +if (bo->pages) +drm_gem_put_pages (dobj, bo->pages, false, false); +drm_gem_object_release (dobj); +kfree (bo); +} + +int sdrm_bo_vmap (struct sdrm_bo *bo) +{ +int r; + +if (!bo->pages) { + bo->pages =drm_gem_get_pages (&bo->base); +if (IS_ERR (bo->pages)) { + r =PTR_ERR (bo->pages); + bo->pages =NULL ; +return r; + } + } + +if (!bo->vmapping) { + bo->vmapping =vmap (bo->pages, bo->base.size /PAGE_SIZE ,0 , +PAGE_KERNEL ); +if (!bo->vmapping) +return -ENOMEM ; + } + +return 0 ; +}
drivers/gpu/drm/simpledrm/simpledrm_gem.c line 80
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_gem.c new file +10
-0+ +int sdrm_dumb_create (struct drm_file *dfile, +struct drm_device *ddev, +struct drm_mode_create_dumb *args) +{ +struct sdrm_bo *bo; +int r; + +/* overflow checks are done by DRM core */ + args->pitch = (args->bpp +7 ) /8 * args->width;
DIV_ROUND_UP?
Quoted 168 lines
drivers/gpu/drm/simpledrm/simpledrm_gem.c new file +29
-0+ args->size =PAGE_ALIGN (args->pitch * args->height); + + bo =sdrm_bo_new (ddev, args->size); +if (!bo) +return -ENOMEM ; + + r =drm_gem_handle_create (dfile, &bo->base, &args->handle); +drm_gem_object_unreference_unlocked (&bo->base); +return r; +} + +int sdrm_dumb_map_offset (struct drm_file *dfile, +struct drm_device *ddev, +uint32_t handle, +uint64_t *offset) +{ +struct drm_gem_object *dobj; +int r; + + dobj =drm_gem_object_lookup (dfile, handle); +if (!dobj) +return -ENOENT ; + + r =drm_gem_create_mmap_offset (dobj); +if (r >=0 ) + *offset =drm_vma_node_offset_addr (&dobj->vma_node); +drm_gem_object_unreference_unlocked (dobj); +return r; +}drivers/gpu/drm/simpledrm/simpledrm_kms.c new file +133
-0@@ -0,0 +1,263 @@ +/* +* Copyright (C) 2012-2016 Red Hat, Inc. +* Copyright (C) 2016 Noralf Trønnes +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <drm/drmP.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_crtc.h> +#include <drm/drm_crtc_helper.h> +#include <drm/drm_gem.h> +#include <drm/drm_simple_kms_helper.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include "simpledrm.h" + +static const uint32_t sdrm_formats[] = { +DRM_FORMAT_RGB565 , +DRM_FORMAT_ARGB8888 , +DRM_FORMAT_XRGB8888 , +}; + +static int sdrm_conn_get_modes (struct drm_connector *conn) +{ +struct sdrm_device *sdrm = conn->dev->dev_private; +struct drm_display_mode *mode; + + mode =drm_cvt_mode (sdrm->ddev, sdrm->hw->width, sdrm->hw->height, +60 , false, false, false); +if (!mode) +return 0 ; + + mode->type =DRM_MODE_TYPE_DRIVER |DRM_MODE_TYPE_PREFERRED ; +drm_mode_set_name (mode); +drm_mode_probed_add (conn, mode); + +return 1 ; +} + +static const struct drm_connector_helper_funcs sdrm_conn_hfuncs = { + .get_modes = sdrm_conn_get_modes, + .best_encoder = drm_atomic_helper_best_encoder, +}; + +static enum drm_connector_status sdrm_conn_detect (struct drm_connector *conn, +bool force) +{ +/* +* We simulate an always connected monitor. simple-fb doesn't +* provide any way to detect whether the connector is active. Hence, +* signal DRM core that it is always connected. +*/ +return connector_status_connected; +} + +static const struct drm_connector_funcs sdrm_conn_ops = { + .dpms = drm_atomic_helper_connector_dpms, + .reset = drm_atomic_helper_connector_reset, + .detect = sdrm_conn_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static void sdrm_crtc_send_vblank_event (struct drm_crtc *crtc) +{ +if (crtc->state && crtc->state->event) { +spin_lock_irq (&crtc->dev->event_lock); +drm_crtc_send_vblank_event (crtc, crtc->state->event); +spin_unlock_irq (&crtc->dev->event_lock); + crtc->state->event =NULL ; + } +} + +void sdrm_display_pipe_update (struct drm_simple_display_pipe *pipe, +struct drm_plane_state *plane_state) +{ +struct drm_framebuffer *dfb = pipe->plane.state->fb; +struct sdrm_fb *fb; + +sdrm_crtc_send_vblank_event (&pipe->crtc); + +if (dfb) { + fb = container_of(dfb, struct sdrm_fb, base); + pipe->plane.fb = dfb; +sdrm_dirty (fb,0 ,0 , dfb->width, dfb->height); + } +} + +static void sdrm_display_pipe_enable (struct drm_simple_display_pipe *pipe, +struct drm_crtc_state *crtc_state) +{ +sdrm_crtc_send_vblank_event (&pipe->crtc); +} + +static void sdrm_display_pipe_disable (struct drm_simple_display_pipe *pipe) +{ +sdrm_crtc_send_vblank_event (&pipe->crtc); +} + +static const struct drm_simple_display_pipe_funcs sdrm_pipe_funcs = { + .update = sdrm_display_pipe_update, + .enable = sdrm_display_pipe_enable, + .disable = sdrm_display_pipe_disable, +}; + +static int sdrm_fb_create_handle (struct drm_framebuffer *dfb, +struct drm_file *dfile, +unsigned int *handle) +{ + struct sdrm_fb *fb = container_of(dfb, struct sdrm_fb, base); + +return drm_gem_handle_create (dfile, &fb->bo->base, handle); +} + +static int sdrm_fb_dirty (struct drm_framebuffer *dfb, +struct drm_file *dfile, +unsigned int flags, +unsigned int color, +struct drm_clip_rect *clips, +unsigned int n_clips) +{ + struct sdrm_fb *fb = container_of(dfb, struct sdrm_fb, base); +struct sdrm_device *sdrm = dfb->dev->dev_private; +unsigned int i; +
drivers/gpu/drm/simpledrm/simpledrm_kms.c line 143
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_kms.c new file +10
-0+drm_modeset_lock_all (sdrm->ddev); +if (dfb == sdrm->pipe.plane.fb) { +if (!clips || !n_clips) { +sdrm_dirty (fb,0 ,0 , dfb->width, dfb->height); + }else { +for (i =0 ; i < n_clips; i++) { +if (clips[i].x1 > clips[i].x2 || + clips[i].x2 > dfb->width || + clips[i].y1 > clips[i].y2 || + clips[i].y2 > dfb->height)
As discussed in private, overlapping clip_rects should be cropped to fit the fb, rather than discarded.
Quoted 175 lines
drivers/gpu/drm/simpledrm/simpledrm_kms.c new file +120
-0+continue ; + +sdrm_dirty (fb, clips[i].x1, clips[i].y1, + clips[i].x2 - clips[i].x1, + clips[i].y2 - clips[i].y1); + } + } + } +drm_modeset_unlock_all (sdrm->ddev); + +return 0 ; +} + +static void sdrm_fb_destroy (struct drm_framebuffer *dfb) +{ + struct sdrm_fb *fb = container_of(dfb, struct sdrm_fb, base); + +drm_framebuffer_cleanup (dfb); +drm_gem_object_unreference_unlocked (&fb->bo->base); +kfree (fb); +} + +static const struct drm_framebuffer_funcs sdrm_fb_ops = { + .create_handle = sdrm_fb_create_handle, + .dirty = sdrm_fb_dirty, + .destroy = sdrm_fb_destroy, +}; + +static struct drm_framebuffer * +sdrm_fb_create (struct drm_device *ddev, +struct drm_file *dfile, +const struct drm_mode_fb_cmd2 *cmd) +{ +struct drm_gem_object *dobj; +struct sdrm_fb *fb =NULL ; +struct sdrm_bo *bo; +int r; + +if (cmd->flags) +return ERR_PTR (-EINVAL ); + + dobj =drm_gem_object_lookup (dfile, cmd->handles[0 ]); +if (!dobj) +return ERR_PTR (-EINVAL ); + + bo = container_of(dobj, struct sdrm_bo, base); + + r =sdrm_bo_vmap (bo); +if (r <0 ) + goto error; + + fb =kzalloc (sizeof (*fb),GFP_KERNEL ); +if (!fb) { + r = -ENOMEM ; + goto error; + } + + fb->bo = bo; +drm_helper_mode_fill_fb_struct (&fb->base, cmd); + + r =drm_framebuffer_init (ddev, &fb->base, &sdrm_fb_ops); +if (r <0 ) + goto error; + +DRM_DEBUG_KMS ("[FB:%d] pixel_format: %s\n" , fb->base.base.id, +drm_get_format_name (fb->base.pixel_format)); + +return &fb->base; + +error: +kfree (fb); +drm_gem_object_unreference_unlocked (dobj); +return ERR_PTR (r); +} + +static const struct drm_mode_config_funcs sdrm_mode_config_ops = { + .fb_create = sdrm_fb_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +int sdrm_kms_bind (struct sdrm_device *sdrm) +{ +struct drm_connector *conn = &sdrm->conn; +struct drm_device *ddev = sdrm->ddev; +int r; + +drm_mode_config_init (ddev); + ddev->mode_config.min_width = sdrm->hw->width; + ddev->mode_config.max_width = sdrm->hw->width; + ddev->mode_config.min_height = sdrm->hw->height; + ddev->mode_config.max_height = sdrm->hw->height; + ddev->mode_config.preferred_depth = sdrm->hw->bpp; + ddev->mode_config.funcs = &sdrm_mode_config_ops; +drm_connector_helper_add (conn, &sdrm_conn_hfuncs); + + r =drm_connector_init (ddev, conn, &sdrm_conn_ops, +DRM_MODE_CONNECTOR_VIRTUAL ); +if (r <0 ) + goto error; + + r =drm_simple_display_pipe_init (ddev, &sdrm->pipe, &sdrm_pipe_funcs, + sdrm_formats, +ARRAY_SIZE (sdrm_formats), conn); +if (r <0 ) + goto error; + +drm_mode_config_reset (ddev); +return 0 ; + +error: +drm_mode_config_cleanup (ddev); +return r; +} + +void sdrm_kms_unbind (struct sdrm_device *sdrm) +{ +if (sdrm->ddev->mode_config.funcs) +drm_mode_config_cleanup (sdrm->ddev); +}drivers/gpu/drm/simpledrm/simpledrm_of.c new file +49
-0@@ -0,0 +1,265 @@ +/* +* Copyright (C) 2012-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <drm/drmP.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include "simpledrm.h" + +#ifdef CONFIG_COMMON_CLK + +static int sdrm_of_bind_clocks (struct sdrm_device *sdrm, +struct device_node *np) +{ +struct clk *clock; +size_t i, n; +int r; + + n =of_clk_get_parent_count (np); +if (n <1 ) +return 0 ; + + sdrm->clks =kcalloc (n,sizeof (*sdrm->clks),GFP_KERNEL ); +if (!sdrm->clks) +return -ENOMEM ; + +for (i =0 ; i < n; ++i) { + clock =of_clk_get (np, i); +if (!IS_ERR (clock)) { + sdrm->clks[sdrm->n_clks++] = clock; + }else if (PTR_ERR (clock) == -EPROBE_DEFER ) { + r = -EPROBE_DEFER ; + goto error; + }else { +dev_err (sdrm->ddev->dev,"cannot find clock %zu: %ld\n" , + i,PTR_ERR (clock)); + }
drivers/gpu/drm/simpledrm/simpledrm_of.c line 59
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_of.c new file +10
-0+ } + +for (i =0 ; i < sdrm->n_clks; ++i) { +if (!sdrm->clks[i]) +continue ; + + r =clk_prepare_enable (sdrm->clks[i]); +if (r <0 ) { +dev_err (sdrm->ddev->dev, +"cannot find clock %zu: %d\n" , i, r);
"cannot enable clock" ?
Quoted 209 lines
drivers/gpu/drm/simpledrm/simpledrm_of.c new file +206
-1+clk_put (sdrm->clks[i]); + sdrm->clks[i] = NULL; + } + } + +return 0 ; + +error: +for (i =0 ; i < sdrm->n_clks; ++i) +clk_put (sdrm->clks[i]); +kfree (sdrm->clks); + sdrm->clks =NULL ; + sdrm->n_clks =0 ; +return r; +} + +static void sdrm_of_unbind_clocks (struct sdrm_device *sdrm) +{ +size_t i; + +for (i =0 ; i < sdrm->n_clks; ++i) { +clk_disable_unprepare (sdrm->clks[i]); +clk_put (sdrm->clks[i]); + } + +kfree (sdrm->clks); + sdrm->clks =NULL ; + sdrm->n_clks =0 ; +} + +#else /* CONFIG_COMMON_CLK */ + +static int sdrm_of_bind_clocks (struct sdrm_device *sdrm, +struct device_node *np) +{ +return 0 ; +} + +static void sdrm_of_unbind_clocks (struct sdrm_device *sdrm) +{ +} + +#endif /* CONFIG_COMMON_CLK */ + +#ifdef CONFIG_REGULATOR + +static int sdrm_of_bind_regulators (struct sdrm_device *sdrm, +struct device_node *np) +{ +struct regulator *regulator; +struct property *prop; +char *p, *name; +size_t i, n; +int r; + + n =0 ; +for_each_property_of_node (np, prop) { + p =strstr (prop->name,"-supply" ); +if (p && p != prop->name) + ++n; + } + +if (n <1 ) +return 0 ; + + sdrm->regulators =kcalloc (n,sizeof (*sdrm->regulators),GFP_KERNEL ); +if (!sdrm->regulators) +return -ENOMEM ; + +for_each_property_of_node (np, prop) { + p =strstr (prop->name,"-supply" ); +if (!p || p == prop->name) +continue ; + + name =kstrndup (prop->name, p - prop->name,GFP_TEMPORARY ); +if (!name) +continue ; + + regulator =regulator_get_optional (sdrm->ddev->dev, name); +kfree (name); + +if (!IS_ERR (regulator)) { + sdrm->regulators[sdrm->n_regulators++] = regulator; + }else if (PTR_ERR (regulator) == -EPROBE_DEFER ) { + r = -EPROBE_DEFER ; + goto error; + }else { +dev_warn (sdrm->ddev->dev, +"cannot find regulator %s: %ld\n" , + prop->name,PTR_ERR (regulator)); + } + } + +for (i =0 ; i < sdrm->n_regulators; ++i) { +if (!sdrm->regulators[i]) +continue ; + + r =regulator_enable (sdrm->regulators[i]); +if (r <0 ) { +dev_warn (sdrm->ddev->dev, +"cannot enable regulator %zu: %d\n" , i, r); +regulator_put (sdrm->regulators[i]); + sdrm->regulators[i] =NULL ; + } + } + +return 0 ; + +error: +for (i =0 ; i < sdrm->n_regulators; ++i) +if (sdrm->regulators[i]) +regulator_put (sdrm->regulators[i]); +kfree (sdrm->regulators); + sdrm->regulators =NULL ; + sdrm->n_regulators =0 ; +return r; +} + +static void sdrm_of_unbind_regulators (struct sdrm_device *sdrm) +{ +size_t i; + +for (i =0 ; i < sdrm->n_regulators; ++i) { +if (sdrm->regulators[i]) { +regulator_disable (sdrm->regulators[i]); +regulator_put (sdrm->regulators[i]); + } + } + +kfree (sdrm->regulators); + sdrm->regulators =NULL ; + sdrm->n_regulators =0 ; +} + +#else /* CONFIG_REGULATORS */ + +static int sdrm_of_bind_regulators (struct sdrm_device *sdrm, +struct device_node *np) +{ +return 0 ; +} + +static void sdrm_of_unbind_regulators (struct sdrm_device *sdrm) +{ +} + +#endif /* CONFIG_REGULATORS */ + +#ifdef CONFIG_OF + +void sdrm_of_bootstrap (void ) +{ +#ifdef CONFIG_OF_ADDRESS +struct device_node *np; + +for_each_compatible_node (np,NULL ,"simple-framebuffer" ) +of_platform_device_create (np,NULL ,NULL ); +#endif +} + +int sdrm_of_bind (struct sdrm_device *sdrm) +{ +int r; + +if (WARN_ON (sdrm->n_clks >0 || sdrm->n_regulators >0 )) +return 0 ; +if (!sdrm->ddev->dev->of_node) +return 0 ; + + r =sdrm_of_bind_clocks (sdrm, sdrm->ddev->dev->of_node); +if (r <0 ) + goto error; + + r =sdrm_of_bind_regulators (sdrm, sdrm->ddev->dev->of_node); +if (r <0 ) + goto error; + +return 0 ; + +error: +sdrm_of_unbind (sdrm); +return r; +} + +void sdrm_of_unbind (struct sdrm_device *sdrm) +{ +sdrm_of_unbind_regulators (sdrm); +sdrm_of_unbind_clocks (sdrm); +} + +#else /* CONFIG_OF */ + +void sdrm_of_bootstrap (void ) +{ +} + +int sdrm_of_bind (struct sdrm_device *sdrm) +{ +return 0 ; +} + +void sdrm_of_unbind (struct sdrm_device *sdrm) +{ +} + +#endif /* CONFIG_OF */ --2.9.3
Quoted 4 lines
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 6/7] drm: add SimpleDRM driver
In reply to David HerrmannDen 02.09.2016 10:22, skrev David Herrmann:
Quoted 12 lines
The SimpleDRM driver binds to simple-framebuffer devices and provides a DRM/KMS API. It provides only a single CRTC+encoder+connector combination plus one initial mode.
Userspace can create dumb-buffers which can be blit into the real framebuffer similar to UDL. No access to the real framebuffer is allowed (compared to earlier version of this driver) to avoid security issues. Furthermore, this way we can support arbitrary modes as long as we have a conversion-helper.
Signed-off-by David Herrmann <[email protected]>---
[...]
Quoted 1 line
drivers/gpu/drm/simpledrm/simpledrm_drv.c +0
-0
[...]
Quoted 13 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c +13
-0+static int sdrm_fop_mmap (struct file *file,struct vm_area_struct *vma) +{ +struct drm_file *dfile = file->private_data; +struct drm_device *dev = dfile->minor->dev; +struct drm_gem_object *obj =NULL ; +struct drm_vma_offset_node *node; +int r; + +drm_vma_offset_lock_lookup (dev->vma_offset_manager); + node =drm_vma_offset_exact_lookup_locked (dev->vma_offset_manager, + vma->vm_pgoff, +vma_pages (vma)); +if (likely (node)) {
drivers/gpu/drm/simpledrm/simpledrm_drv.c line 308
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c +10
-0+ obj = container_of(node, struct drm_gem_object, vma_node); +if (!kref_get_unless_zero (&obj->refcount)) + obj =NULL ; + } +drm_vma_offset_unlock_lookup (dev->vma_offset_manager); + +if (!obj) +return -EINVAL ; + +if (!drm_vma_node_is_allowed (node, dfile)) {
I get:drivers/gpu/drm/simpledrm/simpledrm_drv.c:320:2: warning: passing argument 2 of ‘drm_vma_node_is_allowed’ from incompatible pointer type [enabled by default]
dfile -> file
Quoted 13 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c +13
-0+drm_gem_object_unreference_unlocked (obj); +return -EACCES ; + } + +if (vma->vm_file) +fput (vma->vm_file); + vma->vm_file =get_file (obj->filp); + vma->vm_pgoff =0 ; + + r = obj->filp->f_op->mmap (obj->filp, vma); +drm_gem_object_unreference_unlocked (obj); +return r; +}
[...]
Quoted 1 line
drivers/gpu/drm/simpledrm/simpledrm_kms.c +0
-0
[...]
Quoted 31 lines
drivers/gpu/drm/simpledrm/simpledrm_kms.c +31
-0+static void sdrm_crtc_send_vblank_event (struct drm_crtc *crtc) +{ +if (crtc->state && crtc->state->event) { +spin_lock_irq (&crtc->dev->event_lock); +drm_crtc_send_vblank_event (crtc, crtc->state->event); +spin_unlock_irq (&crtc->dev->event_lock); + crtc->state->event =NULL ; + } +} + +void sdrm_display_pipe_update (struct drm_simple_display_pipe *pipe, +struct drm_plane_state *plane_state) +{ +struct drm_framebuffer *dfb = pipe->plane.state->fb; +struct sdrm_fb *fb; + +sdrm_crtc_send_vblank_event (&pipe->crtc); + +if (dfb) { + fb = container_of(dfb, struct sdrm_fb, base); + pipe->plane.fb = dfb; +sdrm_dirty (fb,0 ,0 , dfb->width, dfb->height); + } +} + +static void sdrm_display_pipe_enable (struct drm_simple_display_pipe *pipe, +struct drm_crtc_state *crtc_state) +{ +sdrm_crtc_send_vblank_event (&pipe->crtc); +} +
drivers/gpu/drm/simpledrm/simpledrm_kms.c line 112
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_kms.c +10
-0+static void sdrm_display_pipe_disable (struct drm_simple_display_pipe *pipe) +{ +sdrm_crtc_send_vblank_event (&pipe->crtc); +} + +static const struct drm_simple_display_pipe_funcs sdrm_pipe_funcs = { + .update = sdrm_display_pipe_update, + .enable = sdrm_display_pipe_enable, + .disable = sdrm_display_pipe_disable, +};
The enable and disable callbacks can be removed. This commit in drm-misc fixed the flip done timeout:
drm/simple-helpers: Always add planes to the state update
Noralf.
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 6/7] drm: add SimpleDRM driver
Hey
Quoted 55 lines · Noralf Trønnes
Den 02.09.2016 10:22, skrev David Herrmann:
Quoted 13 lines
The SimpleDRM driver binds to simple-framebuffer devices and provides a DRM/KMS API. It provides only a single CRTC+encoder+connector combination plus one initial mode.
Userspace can create dumb-buffers which can be blit into the real framebuffer similar to UDL. No access to the real framebuffer is allowed (compared to earlier version of this driver) to avoid security issues. Furthermore, this way we can support arbitrary modes as long as we have a conversion-helper.
Signed-off-by David Herrmann <[email protected]>---
[...]
Quoted 2 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c +0
-0[...]
Quoted 13 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c +13
-0+static int sdrm_fop_mmap (struct file *file,struct vm_area_struct *vma) +{ +struct drm_file *dfile = file->private_data; +struct drm_device *dev = dfile->minor->dev; +struct drm_gem_object *obj =NULL ; +struct drm_vma_offset_node *node; +int r; + +drm_vma_offset_lock_lookup (dev->vma_offset_manager); + node =drm_vma_offset_exact_lookup_locked (dev->vma_offset_manager, + vma->vm_pgoff, +vma_pages (vma)); +if (likely (node)) {drivers/gpu/drm/simpledrm/simpledrm_drv.c line 308
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c +10
-0+ obj = container_of(node, struct drm_gem_object, vma_node); +if (!kref_get_unless_zero (&obj->refcount)) + obj =NULL ; + } +drm_vma_offset_unlock_lookup (dev->vma_offset_manager); + +if (!obj) +return -EINVAL ; + +if (!drm_vma_node_is_allowed (node, dfile)) {I get:
drivers/gpu/drm/simpledrm/simpledrm_drv.c:320:2: warning: passing argument 2 of ‘drm_vma_node_is_allowed’ from incompatible pointer type [enabled by default]
Quoted 1 line
dfile -> file
Yeah, either change that, or apply "[PATCH 0/6] DRM Core Cleanups" before. I suspect the cleanups to go in before this driver, so didn't bother changing it.
Quoted 64 lines
Quoted 13 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c +13
-0+drm_gem_object_unreference_unlocked (obj); +return -EACCES ; + } + +if (vma->vm_file) +fput (vma->vm_file); + vma->vm_file =get_file (obj->filp); + vma->vm_pgoff =0 ; + + r = obj->filp->f_op->mmap (obj->filp, vma); +drm_gem_object_unreference_unlocked (obj); +return r; +}[...]
Quoted 2 lines
drivers/gpu/drm/simpledrm/simpledrm_kms.c +0
-0[...]
Quoted 40 lines
drivers/gpu/drm/simpledrm/simpledrm_kms.c +26
-0+static void sdrm_crtc_send_vblank_event (struct drm_crtc *crtc) +{ +if (crtc->state && crtc->state->event) { +spin_lock_irq (&crtc->dev->event_lock); +drm_crtc_send_vblank_event (crtc, crtc->state->event); +spin_unlock_irq (&crtc->dev->event_lock); + crtc->state->event =NULL ; + } +} + +void sdrm_display_pipe_update (struct drm_simple_display_pipe *pipe, +struct drm_plane_state *plane_state) +{ +struct drm_framebuffer *dfb = pipe->plane.state->fb; +struct sdrm_fb *fb; + +sdrm_crtc_send_vblank_event (&pipe->crtc); + +if (dfb) { + fb = container_of(dfb, struct sdrm_fb, base); + pipe->plane.fb = dfb; +sdrm_dirty (fb,0 ,0 , dfb->width, dfb->height); + } +} + +static void sdrm_display_pipe_enable(struct drm_simple_display_pipe*pipe,
drivers/gpu/drm/simpledrm/simpledrm_kms.c +6
-0+ struct drm_crtc_state *crtc_state) +{ +sdrm_crtc_send_vblank_event (&pipe->crtc); +} + +static void sdrm_display_pipe_disable(struct drm_simple_display_pipe*pipe)
drivers/gpu/drm/simpledrm/simpledrm_kms.c +6
-0+{ +sdrm_crtc_send_vblank_event (&pipe->crtc); +} + +static const struct drm_simple_display_pipe_funcs sdrm_pipe_funcs = { + .update = sdrm_display_pipe_update,
Quoted 8 lines
drivers/gpu/drm/simpledrm/simpledrm_kms.c line 112
Quoted 3 lines
drivers/gpu/drm/simpledrm/simpledrm_kms.c +3
-0+ .enable = sdrm_display_pipe_enable, + .disable = sdrm_display_pipe_disable, +};The enable and disable callbacks can be removed. This commit in drm-misc fixed the flip done timeout:
drm/simple-helpers: Always add planes to the state update
Right, Daniel told me on IRC already. With this fix applied, I can run Xorg on top of it just fine.
I dropped the enable/disable callbacks as well now.
Thanks
David
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 6/7] drm: add SimpleDRM driver
In reply to David HerrmannDen 02.09.2016 10:22, skrev David Herrmann:
Quoted 12 lines
The SimpleDRM driver binds to simple-framebuffer devices and provides a DRM/KMS API. It provides only a single CRTC+encoder+connector combination plus one initial mode.
Userspace can create dumb-buffers which can be blit into the real framebuffer similar to UDL. No access to the real framebuffer is allowed (compared to earlier version of this driver) to avoid security issues. Furthermore, this way we can support arbitrary modes as long as we have a conversion-helper.
Signed-off-by David Herrmann <[email protected]>---
[...]
Quoted 391 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c new file +385
-0@@ -0,0 +1,464 @@ +/* +* Copyright (C) 2012-2016 Red Hat, Inc. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as published by the +* Free Software Foundation; either version 2.1 of the License, or (at your +* option) any later version. +*/ + +#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <drm/drmP.h> +#include <linux/atomic.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_data/simplefb.h> +#include <linux/string.h> +#include "simpledrm.h" + +static struct drm_driver sdrm_drm_driver; +static DEFINE_MUTEX (sdrm_lock); + +static int sdrm_hw_identify (struct platform_device *pdev, +struct simplefb_platform_data *modep, +struct simplefb_format *formatp, +struct resource **memp, +u32 *bppp) +{ +static const struct simplefb_format valid_formats[] =SIMPLEFB_FORMATS ; +struct simplefb_platform_data pm = {}, *mode = pdev->dev.platform_data; +struct device_node *np = pdev->dev.of_node; +const struct simplefb_format *format =NULL ; +struct resource *mem; +unsigned int depth; +int r, bpp; +size_t i; + +if (!mode) { +if (!np) +return -ENODEV ; + + mode = ± + + r =of_property_read_u32 (np,"width" , &mode->width); +if (r >=0 ) + r =of_property_read_u32 (np,"height" , &mode->height); +if (r >=0 ) + r =of_property_read_u32 (np,"stride" , &mode->stride); +if (r >=0 ) + r =of_property_read_string (np,"format" , + &mode->format); +if (r <0 ) +return r; + } + + mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!mem) +return -ENODEV ; + +for (i =0 ; i <ARRAY_SIZE (valid_formats); ++i) { +if (!strcmp (mode->format, valid_formats[i].name)) { + format = &valid_formats[i]; +break ; + } + } + +if (!format) +return -ENODEV ; + +switch (format->fourcc) { +case DRM_FORMAT_RGB565 : +case DRM_FORMAT_XRGB1555 : +case DRM_FORMAT_ARGB1555 : +case DRM_FORMAT_RGB888 : +case DRM_FORMAT_XRGB8888 : +case DRM_FORMAT_ARGB8888 : +case DRM_FORMAT_ABGR8888 : +case DRM_FORMAT_XRGB2101010 : +case DRM_FORMAT_ARGB2101010 : +/* +* You must adjust sdrm_put() whenever you add a new format +* here, otherwise, blitting operations will not work. +* Furthermore, include/linux/platform_data/simplefb.h needs +* to be adjusted so the platform-device actually allows this +* format. +*/ +break ; +default : +return -ENODEV ; + } + +drm_fb_get_bpp_depth (format->fourcc, &depth, &bpp); +if (!bpp) +return -ENODEV ; +if (resource_size (mem) < mode->stride * mode->height) +return -ENODEV ; +if ((bpp +7 ) /8 * mode->width > mode->stride) +return -ENODEV ; + + *modep = *mode; + *formatp = *format; + *memp = mem; + *bppp = bpp; +return 0 ; +} + +static struct sdrm_hw *sdrm_hw_new (const struct simplefb_platform_data *mode, +const struct simplefb_format *format, +const struct resource *mem, +u32 bpp) +{ +struct sdrm_hw *hw; + + hw =kzalloc (sizeof (*hw),GFP_KERNEL ); +if (!hw) +return ERR_PTR (-ENOMEM ); + +mutex_init (&hw->lock); + hw->width = mode->width; + hw->height = mode->height; + hw->stride = mode->stride; + hw->bpp = bpp; + hw->format = format->fourcc; + hw->base = mem->start; + hw->size =resource_size (mem); + +return hw; +} + +static struct sdrm_hw *sdrm_hw_free (struct sdrm_hw *hw) +{ +if (!hw) +return NULL ; + +WARN_ON (hw->map); +mutex_destroy (&hw->lock); +kfree (hw); + +return NULL ; +} + +static int sdrm_hw_bind (struct sdrm_hw *hw) +{ +mutex_lock (&hw->lock); +if (!hw->map) + hw->map =ioremap_wc (hw->base, hw->size); +mutex_unlock (&hw->lock); + +return hw->map ?0 : -EIO ; +} + +static void sdrm_hw_unbind (struct sdrm_hw *hw) +{ +if (!hw) +return ; + +mutex_lock (&hw->lock); +if (hw->map) { +iounmap (hw->map); + hw->map =NULL ; + } +mutex_unlock (&hw->lock); +} + +static struct sdrm_device *sdrm_device_free (struct sdrm_device *sdrm) +{ +if (!sdrm) +return NULL ; + +WARN_ON (atomic_read (&sdrm->n_used) !=INT_MIN ); + sdrm->hw =sdrm_hw_free (sdrm->hw); +drm_dev_unref (sdrm->ddev); +kfree (sdrm); + +return NULL ; +} + +static struct sdrm_device *sdrm_device_new (struct platform_device *pdev, +struct sdrm_hw *hw) +{ +struct sdrm_device *sdrm; +int r; + + sdrm =kzalloc (sizeof (*sdrm),GFP_KERNEL ); +if (!sdrm) +return ERR_PTR (-ENOMEM ); + +atomic_set (&sdrm->n_used,INT_MIN ); + + sdrm->ddev =drm_dev_alloc (&sdrm_drm_driver, &pdev->dev); +if (!sdrm->ddev) { + r = -ENOMEM ; + goto error; + } + + sdrm->ddev->dev_private = sdrm; + sdrm->hw = hw; + +return sdrm; + +error: +sdrm_device_free (sdrm); +return ERR_PTR (r); +} + +static void sdrm_device_unbind (struct sdrm_device *sdrm) +{ +if (sdrm) { +sdrm_kms_unbind (sdrm); +sdrm_hw_unbind (sdrm->hw); +sdrm_of_unbind (sdrm); + } +} + +static int sdrm_device_bind (struct sdrm_device *sdrm) +{ +int r; + + r =sdrm_of_bind (sdrm); +if (r <0 ) + goto error; + + r =sdrm_hw_bind (sdrm->hw); +if (r <0 ) + goto error; + + r =sdrm_kms_bind (sdrm); +if (r <0 ) + goto error; + +return 0 ; + +error: +sdrm_device_unbind (sdrm); +return r; +} + +static int sdrm_device_acquire (struct sdrm_device *sdrm) +{ +return (sdrm &&atomic_inc_unless_negative (&sdrm->n_used)) + ?0 : -ENODEV ; +} + +static void sdrm_device_release (struct sdrm_device *sdrm) +{ +if (sdrm &&atomic_dec_return (&sdrm->n_used) ==INT_MIN ) { +sdrm_device_unbind (sdrm); +sdrm_device_free (sdrm); + } +} + +static int sdrm_fop_open (struct inode *inode,struct file *file) +{ +struct drm_device *ddev; +int r; + +mutex_lock (&sdrm_lock); + r =drm_open (inode, file); +if (r >=0 ) { + ddev = file->private_data; + r =sdrm_device_acquire (ddev->dev_private); +if (r <0 ) +drm_release (inode, file); + } +mutex_unlock (&sdrm_lock); + +return r; +} + +static int sdrm_fop_release (struct inode *inode,struct file *file) +{ +struct drm_file *dfile = file->private_data; +struct drm_device *ddev = dfile->minor->dev; +struct sdrm_device *sdrm = ddev->dev_private; +int res; + + res =drm_release (inode, file); +sdrm_device_release (sdrm); +return res; +} + +static int sdrm_fop_mmap (struct file *file,struct vm_area_struct *vma) +{ +struct drm_file *dfile = file->private_data; +struct drm_device *dev = dfile->minor->dev; +struct drm_gem_object *obj =NULL ; +struct drm_vma_offset_node *node; +int r; + +drm_vma_offset_lock_lookup (dev->vma_offset_manager); + node =drm_vma_offset_exact_lookup_locked (dev->vma_offset_manager, + vma->vm_pgoff, +vma_pages (vma)); +if (likely (node)) { + obj = container_of(node, struct drm_gem_object, vma_node); +if (!kref_get_unless_zero (&obj->refcount)) + obj =NULL ; + } +drm_vma_offset_unlock_lookup (dev->vma_offset_manager); + +if (!obj) +return -EINVAL ; + +if (!drm_vma_node_is_allowed (node, dfile)) { +drm_gem_object_unreference_unlocked (obj); +return -EACCES ; + } + +if (vma->vm_file) +fput (vma->vm_file); + vma->vm_file =get_file (obj->filp); + vma->vm_pgoff =0 ; + + r = obj->filp->f_op->mmap (obj->filp, vma); +drm_gem_object_unreference_unlocked (obj); +return r; +} + +static int sdrm_simplefb_probe (struct platform_device *pdev) +{ +struct simplefb_platform_data hw_mode; +struct simplefb_format hw_format; +struct sdrm_device *sdrm =NULL ; +struct sdrm_hw *hw =NULL ; +struct resource *hw_mem; +u32 hw_bpp; +int r; + + r =sdrm_hw_identify (pdev, &hw_mode, &hw_format, &hw_mem, &hw_bpp); +if (r <0 ) + goto error; + + hw =sdrm_hw_new (&hw_mode, &hw_format, hw_mem, hw_bpp); +if (IS_ERR (hw)) { + r =PTR_ERR (hw); + hw =NULL ; + goto error; + } + + sdrm =sdrm_device_new (pdev, hw); +if (IS_ERR (sdrm)) { + r =PTR_ERR (sdrm); + sdrm =NULL ; + goto error; + } + hw =NULL ; +platform_set_drvdata (pdev, sdrm); + + r =sdrm_device_bind (sdrm); +if (r <0 ) + goto error; + +/* mark device as enabled and acquire bus ref */ +WARN_ON (atomic_read (&sdrm->n_used) !=INT_MIN ); +atomic_set (&sdrm->n_used,1 ); + + r =drm_dev_register (sdrm->ddev,0 ); +if (r <0 ) { +/* mark device as disabled and drop bus ref */ +WARN_ON (atomic_add_return (INT_MIN , &sdrm->n_used) !=INT_MIN ); +sdrm_device_release (sdrm); +return r; + } + +dev_info (sdrm->ddev->dev,"initialized %s on minor %d\n" , + sdrm->ddev->driver->name, sdrm->ddev->primary->index); + +return 0 ; + +error: +sdrm_device_unbind (sdrm); +sdrm_device_free (sdrm); +sdrm_hw_free (hw); +return r; +} + +static int sdrm_simplefb_remove (struct platform_device *pdev) +{ +struct sdrm_device *sdrm =platform_get_drvdata (pdev); + +/* mark device as disabled */
drivers/gpu/drm/simpledrm/simpledrm_drv.c line 395
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c new file +10
-0+atomic_add (INT_MIN , &sdrm->n_used); +sdrm_hw_unbind (sdrm->hw); + +mutex_lock (&sdrm_lock); +drm_dev_unregister (sdrm->ddev); +sdrm_device_release (sdrm); +mutex_unlock (&sdrm_lock); + +return 0 ; +}
There is something wrong with the ref counting.
Load, unload is fine:
$ sudo modprobe simpledrm $ echo 0 | sudo tee /sys/class/vtconsole/vtcon1/bind $ sudo modprobe -r simpledrm $ ls -l /dev/fb* ls: cannot access /dev/fb*: No such file or directory
But if I run modetest in between it's not released:
$ sudo modprobe simpledrm $ ./libdrm/tests/modetest/modetest -M "simpledrm" -s 23:1824x984 setting mode 1824x984-60Hz@XR24 on connectors 23, crtc 25 $ echo 0 | sudo tee /sys/class/vtconsole/vtcon1/bind $ sudo modprobe -r simpledrm $ ls -l /dev/fb* crw-rw---- 1 root video 29, 0 Sep 5 15:43 /dev/fb0
Noralf.
Quoted 60 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c new file +59
-0+ +static const struct file_operations sdrm_drm_fops = { + .owner =THIS_MODULE , + .open = sdrm_fop_open, + .release = sdrm_fop_release, + .mmap = sdrm_fop_mmap, + .poll = drm_poll, + .read = drm_read, + .unlocked_ioctl = drm_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, +#endif + .llseek = noop_llseek, +}; + +static struct drm_driver sdrm_drm_driver = { + .driver_features =DRIVER_GEM |DRIVER_MODESET |DRIVER_ATOMIC , + .fops = &sdrm_drm_fops, + + .gem_free_object = sdrm_bo_free, + + .dumb_create = sdrm_dumb_create, + .dumb_map_offset = sdrm_dumb_map_offset, + .dumb_destroy = drm_gem_dumb_destroy, + + .name ="simpledrm" , + .desc ="Simple firmware framebuffer DRM driver" , + .date ="20160901" , +}; + +static const struct of_device_id sdrm_simplefb_of_match[] = { + { .compatible ="simple-framebuffer" , }, + {}, +}; +MODULE_DEVICE_TABLE (of, sdrm_simplefb_of_match); + +static struct platform_driver sdrm_simplefb_driver = { + .probe = sdrm_simplefb_probe, + .remove = sdrm_simplefb_remove, + .driver = { + .name ="simple-framebuffer" , + .mod_name =KBUILD_MODNAME , + .owner =THIS_MODULE , + .of_match_table = sdrm_simplefb_of_match, + }, +}; + +static int __init sdrm_init (void ) +{ +int r; + + r =platform_driver_register (&sdrm_simplefb_driver); +if (r <0 ) +return r; + +sdrm_of_bootstrap (); +return 0 ; +} +
drivers/gpu/drm/simpledrm/simpledrm_drv.c line 464
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_drv.c new file +10
-0+static void __exit sdrm_exit(void) +{ +platform_driver_unregister (&sdrm_simplefb_driver); +} + +module_init (sdrm_init); +module_exit (sdrm_exit); +MODULE_LICENSE ("GPL" ); +MODULE_DESCRIPTION ("Simple firmware framebuffer DRM driver" ); +MODULE_ALIAS ("platform:simple-framebuffer" );
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v5 7/7 drm/simpledrm: add fbdev fallback support
In reply to David HerrmannCreate a simple fbdev device during SimpleDRM setup so legacy user-space and fbcon can use it.
--- drivers/gpu/drm/simpledrm/Makefile | 1 + drivers/gpu/drm/simpledrm/simpledrm.h | 8 ++ drivers/gpu/drm/simpledrm/simpledrm_drv.c | 13 +++ drivers/gpu/drm/simpledrm/simpledrm_fbdev.c | 143 ++++++++++++++++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_kms.c | 55 ++++++----- 5 files changed, 196 insertions(+), 24 deletions(-) create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_fbdev.c
drivers/gpu/drm/simpledrm/Makefile +1 -0
@@ -1,6 +1,7 @@ simpledrm-y := \ simpledrm_damage.o \ simpledrm_drv.o \ + simpledrm_fbdev.o \ simpledrm_gem.o \ simpledrm_kms.o \ simpledrm_of.o
drivers/gpu/drm/simpledrm/simpledrm.h +8 -0
@@ -19,6 +19,7 @@#include <linux/mutex.h> struct clk ; +struct drm_fb_helper ;struct regulator ;struct simplefb_format ;
@@ -49,6 +50,7 @@ struct sdrm_device {atomic_t n_used;struct drm_device *ddev;struct sdrm_hw *hw; +struct drm_fb_helper *fbdev;size_t n_clks;size_t n_regulators;
@@ -66,6 +68,9 @@ void sdrm_of_unbind(struct sdrm_device *sdrm);int sdrm_kms_bind (struct sdrm_device *sdrm);void sdrm_kms_unbind (struct sdrm_device *sdrm); +void sdrm_fbdev_bind (struct sdrm_device *sdrm); +void sdrm_fbdev_unbind (struct sdrm_device *sdrm); +void sdrm_dirty (struct sdrm_fb *fb,u32 x,u32 y,u32 width,u32 height);struct sdrm_bo *sdrm_bo_new (struct drm_device *ddev,size_t size);
@@ -80,4 +85,7 @@ int sdrm_dumb_map_offset(struct drm_file *dfile,uint32_t handle, uint64_t *offset); +struct sdrm_fb *sdrm_fb_new (struct sdrm_bo *bo, +const struct drm_mode_fb_cmd2 *cmd); +#endif /* __SDRM_SIMPLEDRM_H */
drivers/gpu/drm/simpledrm/simpledrm_drv.c +13 -0
@@ -9,6 +9,7 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt#include <drm/drmP.h> +#include <drm/drm_fb_helper.h> #include <linux/atomic.h> #include <linux/err.h> #include <linux/io.h>
@@ -210,6 +211,7 @@ error:static void sdrm_device_unbind (struct sdrm_device *sdrm) {if (sdrm) { +sdrm_fbdev_unbind (sdrm);sdrm_kms_unbind (sdrm);sdrm_hw_unbind (sdrm->hw);sdrm_of_unbind (sdrm);
@@ -232,6 +234,8 @@ static int sdrm_device_bind(struct sdrm_device *sdrm)if (r <0 ) goto error; +sdrm_fbdev_bind (sdrm); +return 0 ; error:
@@ -253,6 +257,14 @@ static void sdrm_device_release(struct sdrm_device *sdrm) } } +static void sdrm_device_lastclose (struct drm_device *ddev) +{ +struct sdrm_device *sdrm = ddev->dev_private; + +if (sdrm->fbdev) +drm_fb_helper_restore_fbdev_mode_unlocked (sdrm->fbdev); +} +static int sdrm_fop_open (struct inode *inode,struct file *file) {struct drm_device *ddev;
@@ -411,6 +423,7 @@ static const struct file_operations sdrm_drm_fops = {static struct drm_driver sdrm_drm_driver = { .driver_features =DRIVER_GEM |DRIVER_MODESET |DRIVER_ATOMIC , .fops = &sdrm_drm_fops, + .lastclose = sdrm_device_lastclose, .gem_free_object = sdrm_bo_free,
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c new file +143 -0
143 lines not on this page · raw message
drivers/gpu/drm/simpledrm/simpledrm_kms.c +31 -24
84 lines not on this page · raw message
Signature · 6 lines
2.9.3 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 7/7] drm/simpledrm: add fbdev fallback support
Den 02.09.2016 10:22, skrev David Herrmann:
Quoted 4 lines
Create a simple fbdev device during SimpleDRM setup so legacy user-space and fbcon can use it.
Signed-off-by David Herrmann <[email protected]>
[...]
Quoted 1 line
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +0
-0
[...]
Quoted 37 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +37
-0+void sdrm_fbdev_bind (struct sdrm_device *sdrm) +{ +struct drm_fb_helper *fbdev; +int r; + + fbdev =kzalloc (sizeof (*fbdev),GFP_KERNEL ); +if (!fbdev) +return ; + +drm_fb_helper_prepare (sdrm->ddev, fbdev, &sdrm_fbdev_funcs); + + r =drm_fb_helper_init (sdrm->ddev, fbdev,1 ,1 ); +if (r <0 ) + goto error; + + r =drm_fb_helper_single_add_all_connectors (fbdev); +if (r <0 ) + goto error; + + r =drm_fb_helper_initial_config (fbdev, + sdrm->ddev->mode_config.preferred_depth); +if (r <0 ) + goto error; + +if (!fbdev->fbdev) + goto error; + + sdrm->fbdev = fbdev; +return ; + +error: +drm_fb_helper_fini (fbdev); +kfree (fbdev); +} + +void sdrm_fbdev_unbind (struct sdrm_device *sdrm) +{
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c line 139
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +10
-0+struct drm_fb_helper *fbdev = sdrm->fbdev; + +if (!fbdev) +return ; + + sdrm->fbdev =NULL ; +drm_fb_helper_unregister_fbi (fbdev); +cancel_work_sync (&fbdev->dirty_work); +drm_fb_helper_release_fbi (fbdev); +drm_framebuffer_unreference (fbdev->fb);
I get a warning that there are still fb's left during unbind:
[ 48.666003] WARNING: CPU: 0 PID: 716 at drivers/gpu/drm/drm_crtc.c:3855 drm_mode_config_cleanup+0x180/0x1f4 [drm]
This worked:
- drm_framebuffer_unreference(fbdev->fb); + drm_framebuffer_unregister_private(fbdev->fb); + drm_framebuffer_cleanup(fbdev->fb);
Noralf.
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c line 143
Quoted 4 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +4
-0+ fbdev->fb =NULL ; +drm_fb_helper_fini (fbdev); +kfree (fbdev); +}
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 7/7] drm/simpledrm: add fbdev fallback support
Den 03.09.2016 14:04, skrev Noralf Trønnes:
Quoted 68 lines
Den 02.09.2016 10:22, skrev David Herrmann:
Quoted 4 lines
Create a simple fbdev device during SimpleDRM setup so legacy user-space and fbcon can use it.
Signed-off-by David Herrmann <[email protected]>[...]
Quoted 1 line
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +0
-0[...]
Quoted 37 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +37
-0+void sdrm_fbdev_bind (struct sdrm_device *sdrm) +{ +struct drm_fb_helper *fbdev; +int r; + + fbdev =kzalloc (sizeof (*fbdev),GFP_KERNEL ); +if (!fbdev) +return ; + +drm_fb_helper_prepare (sdrm->ddev, fbdev, &sdrm_fbdev_funcs); + + r =drm_fb_helper_init (sdrm->ddev, fbdev,1 ,1 ); +if (r <0 ) + goto error; + + r =drm_fb_helper_single_add_all_connectors (fbdev); +if (r <0 ) + goto error; + + r =drm_fb_helper_initial_config (fbdev, + sdrm->ddev->mode_config.preferred_depth); +if (r <0 ) + goto error; + +if (!fbdev->fbdev) + goto error; + + sdrm->fbdev = fbdev; +return ; + +error: +drm_fb_helper_fini (fbdev); +kfree (fbdev); +} + +void sdrm_fbdev_unbind (struct sdrm_device *sdrm) +{drivers/gpu/drm/simpledrm/simpledrm_fbdev.c line 139
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +10
-0+struct drm_fb_helper *fbdev = sdrm->fbdev; + +if (!fbdev) +return ; + + sdrm->fbdev =NULL ; +drm_fb_helper_unregister_fbi (fbdev); +cancel_work_sync (&fbdev->dirty_work); +drm_fb_helper_release_fbi (fbdev); +drm_framebuffer_unreference (fbdev->fb);I get a warning that there are still fb's left during unbind:
[ 48.666003] WARNING: CPU: 0 PID: 716 at drivers/gpu/drm/drm_crtc.c:3855 drm_mode_config_cleanup+0x180/0x1f4 [drm]This worked:
Review
Quoted 3 lines
(quoted diff) +2
-1- drm_framebuffer_unreference(fbdev->fb); + drm_framebuffer_unregister_private(fbdev->fb); + drm_framebuffer_cleanup(fbdev->fb);
Well not quite, this doesn't free the bo, so maybe this:
- drm_framebuffer_unreference(fbdev->fb); + drm_framebuffer_unregister_private(fbdev->fb); + sdrm_fb_destroy(fbdev->fb);
IIRC the reason ref count doesn't drop to zero, had something to do with multiple fb_set_par calls taking reference but not being dropped later.
Noralf.
Quoted 8 lines
Noralf.
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c line 143
Quoted 4 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +4
-0+ fbdev->fb =NULL ; +drm_fb_helper_fini (fbdev); +kfree (fbdev); +}
Quoted 5 lines
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 7/7] drm/simpledrm: add fbdev fallback support
Hi
Quoted 87 lines · Noralf Trønnes
Den 03.09.2016 14:04, skrev Noralf Trønnes:
Quoted 75 lines
Den 02.09.2016 10:22, skrev David Herrmann:
Quoted 5 lines
Create a simple fbdev device during SimpleDRM setup so legacy user-space and fbcon can use it.
Signed-off-by David Herrmann <[email protected]>[...]
Quoted 2 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +0
-0[...]
Quoted 37 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +37
-0+void sdrm_fbdev_bind (struct sdrm_device *sdrm) +{ +struct drm_fb_helper *fbdev; +int r; + + fbdev =kzalloc (sizeof (*fbdev),GFP_KERNEL ); +if (!fbdev) +return ; + +drm_fb_helper_prepare (sdrm->ddev, fbdev, &sdrm_fbdev_funcs); + + r =drm_fb_helper_init (sdrm->ddev, fbdev,1 ,1 ); +if (r <0 ) + goto error; + + r =drm_fb_helper_single_add_all_connectors (fbdev); +if (r <0 ) + goto error; + + r =drm_fb_helper_initial_config (fbdev, + sdrm->ddev->mode_config.preferred_depth); +if (r <0 ) + goto error; + +if (!fbdev->fbdev) + goto error; + + sdrm->fbdev = fbdev; +return ; + +error: +drm_fb_helper_fini (fbdev); +kfree (fbdev); +} + +void sdrm_fbdev_unbind (struct sdrm_device *sdrm) +{drivers/gpu/drm/simpledrm/simpledrm_fbdev.c line 139
Quoted 10 lines
drivers/gpu/drm/simpledrm/simpledrm_fbdev.c +10
-0+struct drm_fb_helper *fbdev = sdrm->fbdev; + +if (!fbdev) +return ; + + sdrm->fbdev =NULL ; +drm_fb_helper_unregister_fbi (fbdev); +cancel_work_sync (&fbdev->dirty_work); +drm_fb_helper_release_fbi (fbdev); +drm_framebuffer_unreference (fbdev->fb);I get a warning that there are still fb's left during unbind:
[ 48.666003] WARNING: CPU: 0 PID: 716 at drivers/gpu/drm/drm_crtc.c:3855
drm_mode_config_cleanup+0x180/0x1f4[drm]This worked:
Review
Quoted 3 lines
(quoted diff) +2
-1- drm_framebuffer_unreference(fbdev->fb); + drm_framebuffer_unregister_private(fbdev->fb); + drm_framebuffer_cleanup(fbdev->fb);Well not quite, this doesn't free the bo, so maybe this:
(quoted diff) +2
-1- drm_framebuffer_unreference(fbdev->fb); + drm_framebuffer_unregister_private(fbdev->fb); + sdrm_fb_destroy(fbdev->fb);
Quoted 3 lines
IIRC the reason ref count doesn't drop to zero, had something to do with multiple
fb_set_parcalls taking reference but not being dropped later.
So I don't like this at all. If we leak references, we should fix the ref-leak or properly document why this is fine to do. Daniel, what is the exact reason we have unregister_private()? Maybe I should try and trace the ref-leak.
Thanks
David
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 53 lines · EST David Herrmann
Hey
On request of Noralf, I picked up the patches and prepared v5. Works fine with Xorg, if configured according to:
https://lists.freedesktop.org/archives/dri-devel/2014-January/052777.htmlIf anyone knows how to make Xorg pick it up dynamically without such a static configuration, please let me know.
Thanks
DavidDavid Herrmann (7):
x86/sysfb: add support for 64bit EFIlfb_basex86/sysfb: fixlfb_sizecalculation of/platform: exposeof_platform_device_destroy()
video: add generic framebuffer eviction
drm: switch tosysfb_evict_conflicts()
drm: add SimpleDRM driver
drm/simpledrm: add fbdev fallback supportMAINTAINERS | 6 + arch/x86/kernel/sysfb_simplefb.c | 39 ++- drivers/gpu/drm/Kconfig | 3 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 24 +- drivers/gpu/drm/bochs/bochs_drv.c | 19 +- drivers/gpu/drm/i915/i915_drv.c | 73 +--- drivers/gpu/drm/mgag200/mgag200_drv.c | 27 +- drivers/gpu/drm/mgag200/mgag200_main.c | 9 - drivers/gpu/drm/nouveau/nouveau_drm.c | 33 +- drivers/gpu/drm/radeon/radeon_drv.c | 24 +- drivers/gpu/drm/simpledrm/Kconfig | 19 ++ drivers/gpu/drm/simpledrm/Makefile | 9 + drivers/gpu/drm/simpledrm/simpledrm.h | 91 +++++ drivers/gpu/drm/simpledrm/simpledrm_damage.c | 194 +++++++++++ drivers/gpu/drm/simpledrm/simpledrm_drv.c | 477 +++++++++++++++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_fbdev.c | 143 ++++++++ drivers/gpu/drm/simpledrm/simpledrm_gem.c | 109 ++++++ drivers/gpu/drm/simpledrm/simpledrm_kms.c | 270 +++++++++++++++ drivers/gpu/drm/simpledrm/simpledrm_of.c | 265 +++++++++++++++ drivers/gpu/drm/sun4i/sun4i_drv.c | 24 +- drivers/gpu/drm/vc4/vc4_drv.c | 25 +- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 24 +- drivers/of/platform.c | 35 +- drivers/video/Kconfig | 4 + drivers/video/Makefile | 1 + drivers/video/sysfb.c | 327 ++++++++++++++++++ include/linux/of_platform.h | 1 + include/linux/sysfb.h | 34 ++ 29 files changed, 2054 insertions(+), 256 deletions(-) create mode 100644 drivers/gpu/drm/simpledrm/Kconfig create mode 100644 drivers/gpu/drm/simpledrm/Makefile create mode 100644 drivers/gpu/drm/simpledrm/simpledrm.h
Quoted 10 lines
create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_damage.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_drv.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_fbdev.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_gem.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_kms.c create mode 100644 drivers/gpu/drm/simpledrm/simpledrm_of.c create mode 100644 drivers/video/sysfb.c create mode 100644 include/linux/sysfb.h
Hi
I am kind of curious as I do have interest in seeing this merged as well.
There is an email in this thread from 2018, but when I tried to import an mbox file from the whole month for August 2018, for some reason, kmail doesn't see the sender and mailing list recipient in that one, so I will reply to this one, because I was able to import this into my mail client.
https://www.spinics.net/lists/dri-devel/msg185519.html
I was able to get this to build against Linux 4.8, but not against a newer version, some headers seem to have been split, and some things are off by 8 and other things. I could NOT find a git repo, but I was able to find the newest patches I could find, and import those with git am against 4.8 with some tweaks. If that is needed, I can link it, but only if you want.
However in QEMU I wasn't able to figure out how to make it create a /dev/dri/card0 device, even after blacklisting the other modules for qxl, cirrus, etc, and then modprobe-ing simpledrm
In my view something like this is would be useful. There still could be hardware devices that don't have modesetting support (like vmvga in qemu/virt-manager as an example). And most wayland servers need a /dev/dri/card0 device as well as a potential user-mode TTY replacement would also need /dev/dri/card0
I will admit I unfortunately failed to get it to build against master. I couldn't figure out some of the changes, where some new structs were off by a factor of 8.
Thanks
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Thomas Zimmermann
maintainerHi
Am 10.03.21 um 03:50 schrieb nerdopolis:
Quoted 11 lines · EST David Herrmann
Quoted 10 lines
Hey
On request of Noralf, I picked up the patches and prepared v5. Works fine with Xorg, if configured according to:
https://lists.freedesktop.org/archives/dri-devel/2014-January/052777.htmlIf anyone knows how to make Xorg pick it up dynamically without such a static configuration, please let me know.
Quoted 3 lines
Hi
I am kind of curious as I do have interest in seeing this merged as well.
Please take a look at [1]. It's not the same driver, but something to the same effect. I know it's been almost a year, but I do work on this and intend to come back with a new version during 2021.
I currently work on fastboot support for the new driver. But it's a complicated matter and takes time. If there's interest, we could talk about merging what's already there.
Best regards
Thomas
[1] https://lore.kernel.org/dri-devel/[email protected]/
Quoted 37 lines
There is an email in this thread from 2018, but when I tried to import an mbox file from the whole month for August 2018, for some reason, kmail doesn't see the sender and mailing list recipient in that one, so I will reply to this one, because I was able to import this into my mail client.
https://www.spinics.net/lists/dri-devel/msg185519.htmlI was able to get this to build against Linux 4.8, but not against a newer version, some headers seem to have been split, and some things are off by 8 and other things. I could NOT find a git repo, but I was able to find the newest patches I could find, and import those with git am against 4.8 with some tweaks. If that is needed, I can link it, but only if you want.
However in QEMU I wasn't able to figure out how to make it create a
/dev/dri/card0device, even after blacklisting the other modules for qxl, cirrus, etc, and then modprobe-ing simpledrmIn my view something like this is would be useful. There still could be hardware devices that don't have modesetting support (like vmvga in qemu/virt-manager as an example). And most wayland servers need a
/dev/dri/card0device as well as a potential user-mode TTY replacement would also need/dev/dri/card0I will admit I unfortunately failed to get it to build against master. I couldn't figure out some of the changes, where some new structs were off by a factor of 8.
Thanks
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 6 lines
Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 14 lines · EST Thomas Zimmermann
Hi
Am 10.03.21 um 03:50 schrieb nerdopolis:
Quoted 11 lines · EST David Herrmann
Quoted 10 lines
Hey
On request of Noralf, I picked up the patches and prepared v5. Works fine with Xorg, if configured according to:
https://lists.freedesktop.org/archives/dri-devel/2014-January/052777.htmlIf anyone knows how to make Xorg pick it up dynamically without such a static configuration, please let me know.
Quoted 8 lines
Quoted 3 lines
Hi
I am kind of curious as I do have interest in seeing this merged as well.
Please take a look at [1]. It's not the same driver, but something to the same effect. I know it's been almost a year, but I do work on this and intend to come back with a new version during 2021.
Thanks, I'll try that out
Quoted 4 lines
I currently work on fastboot support for the new driver. But it's a complicated matter and takes time. If there's interest, we could talk about merging what's already there.
Quoted 45 lines
Best regards
Thomas[1]
https://lore.kernel.org/dri-devel/[email protected]/Quoted 37 lines
There is an email in this thread from 2018, but when I tried to import an mbox file from the whole month for August 2018, for some reason, kmail doesn't see the sender and mailing list recipient in that one, so I will reply to this one, because I was able to import this into my mail client.
https://www.spinics.net/lists/dri-devel/msg185519.htmlI was able to get this to build against Linux 4.8, but not against a newer version, some headers seem to have been split, and some things are off by 8 and other things. I could NOT find a git repo, but I was able to find the newest patches I could find, and import those with git am against 4.8 with some tweaks. If that is needed, I can link it, but only if you want.
However in QEMU I wasn't able to figure out how to make it create a
/dev/dri/card0device, even after blacklisting the other modules for qxl, cirrus, etc, and then modprobe-ing simpledrmIn my view something like this is would be useful. There still could be hardware devices that don't have modesetting support (like vmvga in qemu/virt-manager as an example). And most wayland servers need a
/dev/dri/card0device as well as a potential user-mode TTY replacement would also need/dev/dri/card0I will admit I unfortunately failed to get it to build against master. I couldn't figure out some of the changes, where some new structs were off by a factor of 8.
Thanks
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 26 lines · EST Thomas Zimmermann
Hi
Am 10.03.21 um 03:50 schrieb nerdopolis:
Quoted 11 lines · EST David Herrmann
Quoted 10 lines
Hey
On request of Noralf, I picked up the patches and prepared v5. Works fine with Xorg, if configured according to:
https://lists.freedesktop.org/archives/dri-devel/2014-January/052777.htmlIf anyone knows how to make Xorg pick it up dynamically without such a static configuration, please let me know.
Quoted 3 lines
Hi
I am kind of curious as I do have interest in seeing this merged as well.
Please take a look at [1]. It's not the same driver, but something to the same effect. I know it's been almost a year, but I do work on this and intend to come back with a new version during 2021.
I currently work on fastboot support for the new driver. But it's a complicated matter and takes time. If there's interest, we could talk about merging what's already there.
Quoted 45 lines
Best regards
Thomas[1]
https://lore.kernel.org/dri-devel/[email protected]/Quoted 37 lines
There is an email in this thread from 2018, but when I tried to import an mbox file from the whole month for August 2018, for some reason, kmail doesn't see the sender and mailing list recipient in that one, so I will reply to this one, because I was able to import this into my mail client.
https://www.spinics.net/lists/dri-devel/msg185519.htmlI was able to get this to build against Linux 4.8, but not against a newer version, some headers seem to have been split, and some things are off by 8 and other things. I could NOT find a git repo, but I was able to find the newest patches I could find, and import those with git am against 4.8 with some tweaks. If that is needed, I can link it, but only if you want.
However in QEMU I wasn't able to figure out how to make it create a
/dev/dri/card0device, even after blacklisting the other modules for qxl, cirrus, etc, and then modprobe-ing simpledrmIn my view something like this is would be useful. There still could be hardware devices that don't have modesetting support (like vmvga in qemu/virt-manager as an example). And most wayland servers need a
/dev/dri/card0device as well as a potential user-mode TTY replacement would also need/dev/dri/card0I will admit I unfortunately failed to get it to build against master. I couldn't figure out some of the changes, where some new structs were off by a factor of 8.
Thanks
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Hi
I tried simplekms against v5.9, and it built, and it runs, and is pretty neat.
I tried using the qxl, cirrus, and vmware card in QEMU. Weston starts on all of them. And I did ensure that the simplekms driver was being used
That is, it works after adding GRUB_GFXPAYLOAD_LINUX=keep , to avoid having to set a VGA option. (although not sure the equivalent in syslinux yet)
Thanks.
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Hi
Am 12.03.21 um 04:49 schrieb nerdopolis:
Quoted 72 lines · EST Thomas Zimmermann
Quoted 26 lines
Hi
Am 10.03.21 um 03:50 schrieb nerdopolis:
Quoted 11 lines · EST David Herrmann
Quoted 10 lines
Hey
On request of Noralf, I picked up the patches and prepared v5. Works fine with Xorg, if configured according to:
https://lists.freedesktop.org/archives/dri-devel/2014-January/052777.htmlIf anyone knows how to make Xorg pick it up dynamically without such a static configuration, please let me know.
Quoted 3 lines
Hi
I am kind of curious as I do have interest in seeing this merged as well.
Please take a look at [1]. It's not the same driver, but something to the same effect. I know it's been almost a year, but I do work on this and intend to come back with a new version during 2021.
I currently work on fastboot support for the new driver. But it's a complicated matter and takes time. If there's interest, we could talk about merging what's already there.
Quoted 45 lines
Best regards
Thomas[1]
https://lore.kernel.org/dri-devel/[email protected]/Quoted 37 lines
There is an email in this thread from 2018, but when I tried to import an mbox file from the whole month for August 2018, for some reason, kmail doesn't see the sender and mailing list recipient in that one, so I will reply to this one, because I was able to import this into my mail client.
https://www.spinics.net/lists/dri-devel/msg185519.htmlI was able to get this to build against Linux 4.8, but not against a newer version, some headers seem to have been split, and some things are off by 8 and other things. I could NOT find a git repo, but I was able to find the newest patches I could find, and import those with git am against 4.8 with some tweaks. If that is needed, I can link it, but only if you want.
However in QEMU I wasn't able to figure out how to make it create a
/dev/dri/card0device, even after blacklisting the other modules for qxl, cirrus, etc, and then modprobe-ing simpledrmIn my view something like this is would be useful. There still could be hardware devices that don't have modesetting support (like vmvga in qemu/virt-manager as an example). And most wayland servers need a
/dev/dri/card0device as well as a potential user-mode TTY replacement would also need/dev/dri/card0I will admit I unfortunately failed to get it to build against master. I couldn't figure out some of the changes, where some new structs were off by a factor of 8.
Thanks
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 6 lines
Hi
I tried simplekms against v5.9, and it built, and it runs, and is pretty neat.
I tried using the qxl, cirrus, and vmware card in QEMU. Weston starts on all of them. And I did ensure that the simplekms driver was being used
Cool! Thanks a lot. When I submit the next patchset can I add
to the tags?
Quoted 3 lines
That is, it works after adding GRUB_GFXPAYLOAD_LINUX=keep , to avoid having to set a VGA option. (although not sure the equivalent in syslinux yet)
Yeah, it's a known 'limitation.' (1) But it's usually something that Linux distributions take care of.
The rsp kernel feature needs a set up from the firmware/bootloader/etc. Once the driver has been merged, added other generic drivers (EFI, VESA, etc) should be a lot easier. Those would maybe not require the firmware setup.
Best regards
Thomas
(1) Well, it's the way it's supposed to work.
Quoted 5 lines
Thanks.
Signature · 6 lines
Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 79 lines · EST Thomas Zimmermann
Hi
Am 12.03.21 um 04:49 schrieb nerdopolis:
Quoted 76 lines · EST Thomas Zimmermann
Quoted 26 lines
Hi
Am 10.03.21 um 03:50 schrieb nerdopolis:
Quoted 11 lines · EST David Herrmann
Quoted 10 lines
Hey
On request of Noralf, I picked up the patches and prepared v5. Works fine with Xorg, if configured according to:
https://lists.freedesktop.org/archives/dri-devel/2014-January/052777.htmlIf anyone knows how to make Xorg pick it up dynamically without such a static configuration, please let me know.
Quoted 3 lines
Hi
I am kind of curious as I do have interest in seeing this merged as well.
Please take a look at [1]. It's not the same driver, but something to the same effect. I know it's been almost a year, but I do work on this and intend to come back with a new version during 2021.
I currently work on fastboot support for the new driver. But it's a complicated matter and takes time. If there's interest, we could talk about merging what's already there.
Quoted 45 lines
Best regards
Thomas[1]
https://lore.kernel.org/dri-devel/[email protected]/Quoted 37 lines
There is an email in this thread from 2018, but when I tried to import an mbox file from the whole month for August 2018, for some reason, kmail doesn't see the sender and mailing list recipient in that one, so I will reply to this one, because I was able to import this into my mail client.
https://www.spinics.net/lists/dri-devel/msg185519.htmlI was able to get this to build against Linux 4.8, but not against a newer version, some headers seem to have been split, and some things are off by 8 and other things. I could NOT find a git repo, but I was able to find the newest patches I could find, and import those with git am against 4.8 with some tweaks. If that is needed, I can link it, but only if you want.
However in QEMU I wasn't able to figure out how to make it create a
/dev/dri/card0device, even after blacklisting the other modules for qxl, cirrus, etc, and then modprobe-ing simpledrmIn my view something like this is would be useful. There still could be hardware devices that don't have modesetting support (like vmvga in qemu/virt-manager as an example). And most wayland servers need a
/dev/dri/card0device as well as a potential user-mode TTY replacement would also need/dev/dri/card0I will admit I unfortunately failed to get it to build against master. I couldn't figure out some of the changes, where some new structs were off by a factor of 8.
Thanks
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-develHi
I tried simplekms against v5.9, and it built, and it runs, and is pretty neat.
Quoted 9 lines
Quoted 2 lines
I tried using the qxl, cirrus, and vmware card in QEMU. Weston starts on all of them. And I did ensure that the simplekms driver was being used
Cool! Thanks a lot. When I submit the next patchset can I add
Tested-by nerdopolis <[email protected]>to the tags?
Sure!
Quoted 12 lines
Quoted 3 lines
That is, it works after adding GRUB_GFXPAYLOAD_LINUX=keep , to avoid having to set a VGA option. (although not sure the equivalent in syslinux yet)
Yeah, it's a known 'limitation.' (1) But it's usually something that Linux distributions take care of.
The rsp kernel feature needs a set up from the
firmware/bootloader/etc. Once the driver has been merged, added other generic drivers (EFI, VESA, etc) should be a lot easier. Those would maybe not require the firmware setup.
Quoted 12 lines
Best regards
Thomas(1) Well, it's the way it's supposed to work.
Quoted 5 lines
Thanks.
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel