v7: - codestype fixes. - new patch, switching i915 to use drm_fb_helper_remove_conflicting_pci_framebuffers v6: buildfix.
Gerd Hoffmann (4): drm: move i915_kick_out_vgacon to vgaarb drm/fb-helper: call vga_remove_vgacon automatically. drm/qxl: remove conflicting framebuffers earlier drm/i915: switch to drm_fb_helper_remove_conflicting_pci_framebuffers
include/drm/drm_fb_helper.h | 14 ++++++-- include/linux/vgaarb.h | 2 ++ drivers/gpu/drm/i915/i915_drv.c | 71 ++--------------------------------------- drivers/gpu/drm/qxl/qxl_drv.c | 5 ++- drivers/gpu/vga/vgaarb.c | 49 ++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 73 deletions(-)
Also rename it to vga_remove_vgacon and add kerneldoc text.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch --- include/linux/vgaarb.h | 2 ++ drivers/gpu/drm/i915/i915_drv.c | 35 +---------------------------- drivers/gpu/vga/vgaarb.c | 49 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 34 deletions(-)
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h index ee162e3e879b..553b34c8b5f7 100644 --- a/include/linux/vgaarb.h +++ b/include/linux/vgaarb.h @@ -125,9 +125,11 @@ extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); #ifdef CONFIG_VGA_ARB extern struct pci_dev *vga_default_device(void); extern void vga_set_default_device(struct pci_dev *pdev); +extern int vga_remove_vgacon(struct pci_dev *pdev); #else static inline struct pci_dev *vga_default_device(void) { return NULL; }; static inline void vga_set_default_device(struct pci_dev *pdev) { }; +static inline int vga_remove_vgacon(struct pci_dev *pdev) { return 0; }; #endif
/* diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6630212f2faf..9df65d386d11 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -757,39 +757,6 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) return ret; }
-#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; - - DRM_INFO("Replacing VGA console driver\n"); - - 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); - - /* Ignore "already unregistered". */ - if (ret == -ENODEV) - ret = 0; - } - console_unlock(); - - return ret; -} -#endif - static void intel_init_dpio(struct drm_i915_private *dev_priv) { /* @@ -1420,7 +1387,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) goto err_ggtt; }
- ret = i915_kick_out_vgacon(dev_priv); + ret = vga_remove_vgacon(pdev); if (ret) { DRM_ERROR("failed to remove conflicting VGA console\n"); goto err_ggtt; diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index dc8e039bfab5..f2f3ef8af271 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -48,6 +48,8 @@ #include <linux/miscdevice.h> #include <linux/slab.h> #include <linux/screen_info.h> +#include <linux/vt.h> +#include <linux/console.h>
#include <linux/uaccess.h>
@@ -168,6 +170,53 @@ void vga_set_default_device(struct pci_dev *pdev) vga_default = pci_dev_get(pdev); }
+/** + * vga_remove_vgacon - deactivete vga console + * + * Unbind and unregister vgacon in case pdev is the default vga + * device. Can be called by gpu drivers on initialization to make + * sure vga register access done by vgacon will not disturb the + * device. + * + * @pdev: pci device. + */ +#if !defined(CONFIG_VGA_CONSOLE) +int vga_remove_vgacon(struct pci_dev *pdev) +{ + return 0; +} +#elif !defined(CONFIG_DUMMY_CONSOLE) +int vga_remove_vgacon(struct pci_dev *pdev) +{ + return -ENODEV; +} +#else +int vga_remove_vgacon(struct pci_dev *pdev) +{ + int ret = 0; + + if (pdev != vga_default) + return 0; + vgaarb_info(&pdev->dev, "deactivate vga console\n"); + + 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); + + /* Ignore "already unregistered". */ + if (ret == -ENODEV) + ret = 0; + } + console_unlock(); + + return ret; +} +#endif +EXPORT_SYMBOL(vga_remove_vgacon); + static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) { if (vgadev->irq_set_state)
Add vga_remove_vgacon() call to drm_fb_helper_remove_conflicting_pci_framebuffers().
Signed-off-by: Gerd Hoffmann kraxel@redhat.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch --- include/drm/drm_fb_helper.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index bb9acea61369..286d58efed5d 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -36,6 +36,7 @@ struct drm_fb_helper; #include <drm/drm_crtc.h> #include <drm/drm_device.h> #include <linux/kgdb.h> +#include <linux/vgaarb.h>
enum mode_set_atomic { LEAVE_ATOMIC_MODE_SET, @@ -642,11 +643,18 @@ drm_fb_helper_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int resource_id, const char *name) { + int ret = 0; + + /* + * WARNING: Apparently we must kick fbdev drivers before vgacon, + * otherwise the vga fbdev driver falls over. + */ #if IS_REACHABLE(CONFIG_FB) - return remove_conflicting_pci_framebuffers(pdev, resource_id, name); -#else - return 0; + ret = remove_conflicting_pci_framebuffers(pdev, resource_id, name); #endif + if (ret == 0) + ret = vga_remove_vgacon(pdev); + return ret; }
#endif
Add error checking while being at it.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch --- drivers/gpu/drm/qxl/qxl_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index bb81e310eb6d..578d867a81d5 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -79,6 +79,10 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto free_dev;
+ ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "qxl"); + if (ret) + goto disable_pci; + ret = qxl_device_init(qdev, &qxl_driver, pdev); if (ret) goto disable_pci; @@ -94,7 +98,6 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto modeset_cleanup;
- drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "qxl"); drm_fbdev_generic_setup(&qdev->ddev, 32); return 0;
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- drivers/gpu/drm/i915/i915_drv.c | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9df65d386d11..c6f1e0dbdd58 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -732,31 +732,6 @@ static int i915_load_modeset_init(struct drm_device *dev) return ret; }
-static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) -{ - struct apertures_struct *ap; - 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->gmadr.start; - ap->ranges[0].size = ggtt->mappable_end; - - primary = - pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - - ret = drm_fb_helper_remove_conflicting_framebuffers(ap, "inteldrmfb", primary); - - kfree(ap); - - return ret; -} - static void intel_init_dpio(struct drm_i915_private *dev_priv) { /* @@ -1377,22 +1352,13 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) if (ret) goto err_perf;
- /* - * WARNING: Apparently we must kick fbdev drivers before vgacon, - * otherwise the vga fbdev driver falls over. - */ - ret = i915_kick_out_firmware_fb(dev_priv); + ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 2, + "inteldrmfb"); if (ret) { DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); goto err_ggtt; }
- ret = vga_remove_vgacon(pdev); - if (ret) { - DRM_ERROR("failed to remove conflicting VGA console\n"); - goto err_ggtt; - } - ret = i915_ggtt_init_hw(dev_priv); if (ret) goto err_ggtt;
On Fri, Mar 01, 2019 at 10:25:02AM +0100, Gerd Hoffmann wrote:
Signed-off-by: Gerd Hoffmann kraxel@redhat.com
drivers/gpu/drm/i915/i915_drv.c | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9df65d386d11..c6f1e0dbdd58 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -732,31 +732,6 @@ static int i915_load_modeset_init(struct drm_device *dev) return ret; }
-static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) -{
- struct apertures_struct *ap;
- 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->gmadr.start;
- ap->ranges[0].size = ggtt->mappable_end;
- primary =
pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
- ret = drm_fb_helper_remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
- kfree(ap);
- return ret;
-}
static void intel_init_dpio(struct drm_i915_private *dev_priv) { /* @@ -1377,22 +1352,13 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) if (ret) goto err_perf;
- /*
* WARNING: Apparently we must kick fbdev drivers before vgacon,
* otherwise the vga fbdev driver falls over.
*/
- ret = i915_kick_out_firmware_fb(dev_priv);
- ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 2,
"inteldrmfb");
Ok I reviewed this more carefully, it moves around:
- gen2: bar 0 - gen3-5: bar 1 - gen6+: bar 2
I think the 100% future proof version would be to change the helper in the fb core to just have apertures mapping all bars of the passed-in pci device, and remove the bar number. Then we could apply this patch without having to duplicate the knowledge about which pci bar the fb can sit in.
If you don't feel like typing this (since quite a bit of scope creep with my comments already ...) a patch to add it to todo.rst would be great.
Thanks, Daniel
if (ret) { DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); goto err_ggtt; }
- ret = vga_remove_vgacon(pdev);
- if (ret) {
DRM_ERROR("failed to remove conflicting VGA console\n");
goto err_ggtt;
- }
- ret = i915_ggtt_init_hw(dev_priv); if (ret) goto err_ggtt;
-- 2.9.3
dri-devel@lists.freedesktop.org