Hi Greg,
Here is a series of various cleanups and other prep. work for moving the vboxvideo driver over to atomic modesetting so that it can be moved out of staging.
Regards,
Hans
Registering the connector explicitly right after creation is not necessary for modesetting drivers, because drm_dev_register already takes care of this on the core side, by calling drm_modeset_register_all.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_mode.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index e7d70ced5bfd..70701a6054c2 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -690,7 +690,6 @@ static int vbox_connector_init(struct drm_device *dev, dev->mode_config.suggested_x_property, 0); drm_object_attach_property(&connector->base, dev->mode_config.suggested_y_property, 0); - drm_connector_register(connector);
drm_connector_attach_encoder(connector, encoder);
Move the setup of drm modesetting config from vbox_driver_load() to vbox_mode_init().
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_main.c | 45 ------------------- drivers/staging/vboxvideo/vbox_mode.c | 62 ++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 50 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c index 783a68c0de3b..a1cd29fe98fd 100644 --- a/drivers/staging/vboxvideo/vbox_main.c +++ b/drivers/staging/vboxvideo/vbox_main.c @@ -173,40 +173,6 @@ int vbox_framebuffer_init(struct drm_device *dev, return 0; }
-static struct drm_framebuffer *vbox_user_framebuffer_create( - struct drm_device *dev, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_gem_object *obj; - struct vbox_framebuffer *vbox_fb; - int ret = -ENOMEM; - - obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); - if (!obj) - return ERR_PTR(-ENOENT); - - vbox_fb = kzalloc(sizeof(*vbox_fb), GFP_KERNEL); - if (!vbox_fb) - goto err_unref_obj; - - ret = vbox_framebuffer_init(dev, vbox_fb, mode_cmd, obj); - if (ret) - goto err_free_vbox_fb; - - return &vbox_fb->base; - -err_free_vbox_fb: - kfree(vbox_fb); -err_unref_obj: - drm_gem_object_put_unlocked(obj); - return ERR_PTR(ret); -} - -static const struct drm_mode_config_funcs vbox_mode_funcs = { - .fb_create = vbox_user_framebuffer_create, -}; - static int vbox_accel_init(struct vbox_private *vbox) { unsigned int i; @@ -375,15 +341,6 @@ int vbox_driver_load(struct drm_device *dev) if (ret) goto err_hw_fini;
- drm_mode_config_init(dev); - - dev->mode_config.funcs = (void *)&vbox_mode_funcs; - dev->mode_config.min_width = 64; - dev->mode_config.min_height = 64; - dev->mode_config.preferred_depth = 24; - dev->mode_config.max_width = VBE_DISPI_MAX_XRES; - dev->mode_config.max_height = VBE_DISPI_MAX_YRES; - ret = vbox_mode_init(dev); if (ret) goto err_drm_mode_cleanup; @@ -403,7 +360,6 @@ int vbox_driver_load(struct drm_device *dev) err_mode_fini: vbox_mode_fini(dev); err_drm_mode_cleanup: - drm_mode_config_cleanup(dev); vbox_mm_fini(vbox); err_hw_fini: vbox_hw_fini(vbox); @@ -417,7 +373,6 @@ void vbox_driver_unload(struct drm_device *dev) vbox_fbdev_fini(dev); vbox_irq_fini(vbox); vbox_mode_fini(dev); - drm_mode_config_cleanup(dev); vbox_mm_fini(vbox); vbox_hw_fini(vbox); } diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 70701a6054c2..2587e6aecca2 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -696,6 +696,40 @@ static int vbox_connector_init(struct drm_device *dev, return 0; }
+static struct drm_framebuffer *vbox_user_framebuffer_create( + struct drm_device *dev, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct drm_gem_object *obj; + struct vbox_framebuffer *vbox_fb; + int ret = -ENOMEM; + + obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); + if (!obj) + return ERR_PTR(-ENOENT); + + vbox_fb = kzalloc(sizeof(*vbox_fb), GFP_KERNEL); + if (!vbox_fb) + goto err_unref_obj; + + ret = vbox_framebuffer_init(dev, vbox_fb, mode_cmd, obj); + if (ret) + goto err_free_vbox_fb; + + return &vbox_fb->base; + +err_free_vbox_fb: + kfree(vbox_fb); +err_unref_obj: + drm_gem_object_put_unlocked(obj); + return ERR_PTR(ret); +} + +static const struct drm_mode_config_funcs vbox_mode_funcs = { + .fb_create = vbox_user_framebuffer_create, +}; + int vbox_mode_init(struct drm_device *dev) { struct vbox_private *vbox = dev->dev_private; @@ -704,24 +738,42 @@ int vbox_mode_init(struct drm_device *dev) unsigned int i; int ret;
+ drm_mode_config_init(dev); + + dev->mode_config.funcs = (void *)&vbox_mode_funcs; + dev->mode_config.min_width = 64; + dev->mode_config.min_height = 64; + dev->mode_config.preferred_depth = 24; + dev->mode_config.max_width = VBE_DISPI_MAX_XRES; + dev->mode_config.max_height = VBE_DISPI_MAX_YRES; + /* vbox_cursor_init(dev); */ for (i = 0; i < vbox->num_crtcs; ++i) { vbox_crtc = vbox_crtc_init(dev, i); - if (!vbox_crtc) - return -ENOMEM; + if (!vbox_crtc) { + ret = -ENOMEM; + goto err_drm_mode_cleanup; + } encoder = vbox_encoder_init(dev, i); - if (!encoder) - return -ENOMEM; + if (!encoder) { + ret = -ENOMEM; + goto err_drm_mode_cleanup; + } ret = vbox_connector_init(dev, vbox_crtc, encoder); if (ret) - return ret; + goto err_drm_mode_cleanup; }
return 0; + +err_drm_mode_cleanup: + drm_mode_config_cleanup(dev); + return ret; }
void vbox_mode_fini(struct drm_device *dev) { + drm_mode_config_cleanup(dev); /* vbox_cursor_fini(dev); */ }
Fold the driver_load / unload functions into the probe / remove functions now that we are no longer using the deprecated drm_get_pci_dev() mechanism.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_drv.c | 71 +++++++++++++++++++++------ drivers/staging/vboxvideo/vbox_drv.h | 6 ++- drivers/staging/vboxvideo/vbox_main.c | 67 ++----------------------- 3 files changed, 63 insertions(+), 81 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c index 69cc508af1bc..410a1f35b746 100644 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ b/drivers/staging/vboxvideo/vbox_drv.c @@ -51,48 +51,89 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct vbox_private *vbox = NULL; struct drm_device *dev = NULL; int ret = 0;
+ if (!vbox_check_supported(VBE_DISPI_ID_HGSMI)) + return -ENODEV; + dev = drm_dev_alloc(&driver, &pdev->dev); - if (IS_ERR(dev)) { - ret = PTR_ERR(dev); - goto err_drv_alloc; - } + if (IS_ERR(dev)) + return PTR_ERR(dev);
ret = pci_enable_device(pdev); if (ret) - goto err_pci_enable; + goto err_dev_put;
dev->pdev = pdev; pci_set_drvdata(pdev, dev);
- ret = vbox_driver_load(dev); + vbox = devm_kzalloc(&pdev->dev, sizeof(*vbox), GFP_KERNEL); + if (!vbox) { + ret = -ENOMEM; + goto err_pci_disable; + } + + dev->dev_private = vbox; + vbox->dev = dev; + + mutex_init(&vbox->hw_mutex); + + ret = vbox_hw_init(vbox); + if (ret) + goto err_pci_disable; + + ret = vbox_mm_init(vbox); if (ret) - goto err_vbox_driver_load; + goto err_hw_fini; + + ret = vbox_mode_init(dev); + if (ret) + goto err_mm_fini; + + ret = vbox_irq_init(vbox); + if (ret) + goto err_mode_fini; + + ret = vbox_fbdev_init(dev); + if (ret) + goto err_irq_fini;
ret = drm_dev_register(dev, 0); if (ret) - goto err_drv_dev_register; + goto err_fbdev_fini;
- return ret; + return 0;
- err_drv_dev_register: - vbox_driver_unload(dev); - err_vbox_driver_load: +err_fbdev_fini: + vbox_fbdev_fini(dev); +err_irq_fini: + vbox_irq_fini(vbox); +err_mode_fini: + vbox_mode_fini(dev); +err_mm_fini: + vbox_mm_fini(vbox); +err_hw_fini: + vbox_hw_fini(vbox); +err_pci_disable: pci_disable_device(pdev); - err_pci_enable: +err_dev_put: drm_dev_put(dev); - err_drv_alloc: return ret; }
static void vbox_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); + struct vbox_private *vbox = dev->dev_private;
drm_dev_unregister(dev); - vbox_driver_unload(dev); + vbox_fbdev_fini(dev); + vbox_irq_fini(vbox); + vbox_mode_fini(dev); + vbox_mm_fini(vbox); + vbox_hw_fini(vbox); drm_dev_put(dev); }
diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h index 594f84272957..a8e0dd8b57bf 100644 --- a/drivers/staging/vboxvideo/vbox_drv.h +++ b/drivers/staging/vboxvideo/vbox_drv.h @@ -126,8 +126,6 @@ struct vbox_private { #undef CURSOR_PIXEL_COUNT #undef CURSOR_DATA_SIZE
-int vbox_driver_load(struct drm_device *dev); -void vbox_driver_unload(struct drm_device *dev); void vbox_driver_lastclose(struct drm_device *dev);
struct vbox_gem_object; @@ -177,6 +175,10 @@ struct vbox_fbdev { #define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base) #define to_vbox_framebuffer(x) container_of(x, struct vbox_framebuffer, base)
+bool vbox_check_supported(u16 id); +int vbox_hw_init(struct vbox_private *vbox); +void vbox_hw_fini(struct vbox_private *vbox); + int vbox_mode_init(struct drm_device *dev); void vbox_mode_fini(struct drm_device *dev);
diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c index a1cd29fe98fd..815292f1d7e6 100644 --- a/drivers/staging/vboxvideo/vbox_main.c +++ b/drivers/staging/vboxvideo/vbox_main.c @@ -228,7 +228,7 @@ static bool have_hgsmi_mode_hints(struct vbox_private *vbox) return have_hints == VINF_SUCCESS && have_cursor == VINF_SUCCESS; }
-static bool vbox_check_supported(u16 id) +bool vbox_check_supported(u16 id) { u16 dispi_id;
@@ -242,7 +242,7 @@ static bool vbox_check_supported(u16 id) * Set up our heaps and data exchange buffers in VRAM before handing the rest * to the memory manager. */ -static int vbox_hw_init(struct vbox_private *vbox) +int vbox_hw_init(struct vbox_private *vbox) { int ret = -ENOMEM;
@@ -309,74 +309,13 @@ static int vbox_hw_init(struct vbox_private *vbox) return ret; }
-static void vbox_hw_fini(struct vbox_private *vbox) +void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox); gen_pool_destroy(vbox->guest_pool); pci_iounmap(vbox->dev->pdev, vbox->guest_heap); }
-int vbox_driver_load(struct drm_device *dev) -{ - struct vbox_private *vbox; - int ret = 0; - - if (!vbox_check_supported(VBE_DISPI_ID_HGSMI)) - return -ENODEV; - - vbox = devm_kzalloc(dev->dev, sizeof(*vbox), GFP_KERNEL); - if (!vbox) - return -ENOMEM; - - dev->dev_private = vbox; - vbox->dev = dev; - - mutex_init(&vbox->hw_mutex); - - ret = vbox_hw_init(vbox); - if (ret) - return ret; - - ret = vbox_mm_init(vbox); - if (ret) - goto err_hw_fini; - - ret = vbox_mode_init(dev); - if (ret) - goto err_drm_mode_cleanup; - - ret = vbox_irq_init(vbox); - if (ret) - goto err_mode_fini; - - ret = vbox_fbdev_init(dev); - if (ret) - goto err_irq_fini; - - return 0; - -err_irq_fini: - vbox_irq_fini(vbox); -err_mode_fini: - vbox_mode_fini(dev); -err_drm_mode_cleanup: - vbox_mm_fini(vbox); -err_hw_fini: - vbox_hw_fini(vbox); - return ret; -} - -void vbox_driver_unload(struct drm_device *dev) -{ - struct vbox_private *vbox = dev->dev_private; - - vbox_fbdev_fini(dev); - vbox_irq_fini(vbox); - vbox_mode_fini(dev); - vbox_mm_fini(vbox); - vbox_hw_fini(vbox); -} - /** * @note this is described in the DRM framework documentation. AST does not * have it, but we get an oops on driver unload if it is not present.
This is the recommended way to create the drm_device structure, according to DRM documentation.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_drv.c | 110 +++++++++++--------------- drivers/staging/vboxvideo/vbox_drv.h | 17 ++-- drivers/staging/vboxvideo/vbox_fb.c | 19 ++--- drivers/staging/vboxvideo/vbox_irq.c | 8 +- drivers/staging/vboxvideo/vbox_main.c | 30 +++---- drivers/staging/vboxvideo/vbox_mode.c | 36 ++++----- drivers/staging/vboxvideo/vbox_ttm.c | 13 ++- 7 files changed, 111 insertions(+), 122 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c index 410a1f35b746..c4290d4b4a53 100644 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ b/drivers/staging/vboxvideo/vbox_drv.c @@ -51,35 +51,31 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct vbox_private *vbox = NULL; - struct drm_device *dev = NULL; + struct vbox_private *vbox; int ret = 0;
if (!vbox_check_supported(VBE_DISPI_ID_HGSMI)) return -ENODEV;
- dev = drm_dev_alloc(&driver, &pdev->dev); - if (IS_ERR(dev)) - return PTR_ERR(dev); + vbox = kzalloc(sizeof(*vbox), GFP_KERNEL); + if (!vbox) + return -ENOMEM;
- ret = pci_enable_device(pdev); - if (ret) - goto err_dev_put; - - dev->pdev = pdev; - pci_set_drvdata(pdev, dev); - - vbox = devm_kzalloc(&pdev->dev, sizeof(*vbox), GFP_KERNEL); - if (!vbox) { - ret = -ENOMEM; - goto err_pci_disable; + ret = drm_dev_init(&vbox->ddev, &driver, &pdev->dev); + if (ret) { + kfree(vbox); + return ret; }
- dev->dev_private = vbox; - vbox->dev = dev; - + vbox->ddev.pdev = pdev; + vbox->ddev.dev_private = vbox; + pci_set_drvdata(pdev, vbox); mutex_init(&vbox->hw_mutex);
+ ret = pci_enable_device(pdev); + if (ret) + goto err_dev_put; + ret = vbox_hw_init(vbox); if (ret) goto err_pci_disable; @@ -88,7 +84,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto err_hw_fini;
- ret = vbox_mode_init(dev); + ret = vbox_mode_init(vbox); if (ret) goto err_mm_fini;
@@ -96,22 +92,22 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto err_mode_fini;
- ret = vbox_fbdev_init(dev); + ret = vbox_fbdev_init(vbox); if (ret) goto err_irq_fini;
- ret = drm_dev_register(dev, 0); + ret = drm_dev_register(&vbox->ddev, 0); if (ret) goto err_fbdev_fini;
return 0;
err_fbdev_fini: - vbox_fbdev_fini(dev); + vbox_fbdev_fini(vbox); err_irq_fini: vbox_irq_fini(vbox); err_mode_fini: - vbox_mode_fini(dev); + vbox_mode_fini(vbox); err_mm_fini: vbox_mm_fini(vbox); err_hw_fini: @@ -119,110 +115,100 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err_pci_disable: pci_disable_device(pdev); err_dev_put: - drm_dev_put(dev); + drm_dev_put(&vbox->ddev); return ret; }
static void vbox_pci_remove(struct pci_dev *pdev) { - struct drm_device *dev = pci_get_drvdata(pdev); - struct vbox_private *vbox = dev->dev_private; + struct vbox_private *vbox = pci_get_drvdata(pdev);
- drm_dev_unregister(dev); - vbox_fbdev_fini(dev); + drm_dev_unregister(&vbox->ddev); + vbox_fbdev_fini(vbox); vbox_irq_fini(vbox); - vbox_mode_fini(dev); + vbox_mode_fini(vbox); vbox_mm_fini(vbox); vbox_hw_fini(vbox); - drm_dev_put(dev); + drm_dev_put(&vbox->ddev); }
-static int vbox_drm_freeze(struct drm_device *dev) +static int vbox_drm_freeze(struct vbox_private *vbox) { - struct vbox_private *vbox = dev->dev_private; - - drm_kms_helper_poll_disable(dev); + drm_kms_helper_poll_disable(&vbox->ddev);
- pci_save_state(dev->pdev); + pci_save_state(vbox->ddev.pdev);
drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, true);
return 0; }
-static int vbox_drm_thaw(struct drm_device *dev) +static int vbox_drm_thaw(struct vbox_private *vbox) { - struct vbox_private *vbox = dev->dev_private; - - drm_mode_config_reset(dev); - drm_helper_resume_force_mode(dev); + drm_mode_config_reset(&vbox->ddev); + drm_helper_resume_force_mode(&vbox->ddev); drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, false);
return 0; }
-static int vbox_drm_resume(struct drm_device *dev) +static int vbox_drm_resume(struct vbox_private *vbox) { int ret;
- if (pci_enable_device(dev->pdev)) + if (pci_enable_device(vbox->ddev.pdev)) return -EIO;
- ret = vbox_drm_thaw(dev); + ret = vbox_drm_thaw(vbox); if (ret) return ret;
- drm_kms_helper_poll_enable(dev); + drm_kms_helper_poll_enable(&vbox->ddev);
return 0; }
static int vbox_pm_suspend(struct device *dev) { - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *ddev = pci_get_drvdata(pdev); + struct vbox_private *vbox = dev_get_drvdata(dev); int error;
- error = vbox_drm_freeze(ddev); + error = vbox_drm_freeze(vbox); if (error) return error;
- pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); + pci_disable_device(vbox->ddev.pdev); + pci_set_power_state(vbox->ddev.pdev, PCI_D3hot);
return 0; }
static int vbox_pm_resume(struct device *dev) { - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); + struct vbox_private *vbox = dev_get_drvdata(dev);
- return vbox_drm_resume(ddev); + return vbox_drm_resume(vbox); }
static int vbox_pm_freeze(struct device *dev) { - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *ddev = pci_get_drvdata(pdev); - - if (!ddev || !ddev->dev_private) - return -ENODEV; + struct vbox_private *vbox = dev_get_drvdata(dev);
- return vbox_drm_freeze(ddev); + return vbox_drm_freeze(vbox); }
static int vbox_pm_thaw(struct device *dev) { - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); + struct vbox_private *vbox = dev_get_drvdata(dev);
- return vbox_drm_thaw(ddev); + return vbox_drm_thaw(vbox); }
static int vbox_pm_poweroff(struct device *dev) { - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); + struct vbox_private *vbox = dev_get_drvdata(dev);
- return vbox_drm_freeze(ddev); + return vbox_drm_freeze(vbox); }
static const struct dev_pm_ops vbox_pm_ops = { diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h index a8e0dd8b57bf..28ffdffe877a 100644 --- a/drivers/staging/vboxvideo/vbox_drv.h +++ b/drivers/staging/vboxvideo/vbox_drv.h @@ -75,7 +75,8 @@ struct vbox_fbdev;
struct vbox_private { - struct drm_device *dev; + /* Must be first; or we must define our own release callback */ + struct drm_device ddev;
u8 __iomem *guest_heap; u8 __iomem *vbva_buffers; @@ -179,8 +180,8 @@ bool vbox_check_supported(u16 id); int vbox_hw_init(struct vbox_private *vbox); void vbox_hw_fini(struct vbox_private *vbox);
-int vbox_mode_init(struct drm_device *dev); -void vbox_mode_fini(struct drm_device *dev); +int vbox_mode_init(struct vbox_private *vbox); +void vbox_mode_fini(struct vbox_private *vbox);
#define DRM_MODE_FB_CMD drm_mode_fb_cmd2 #define CRTC_FB(crtc) ((crtc)->primary->fb) @@ -193,13 +194,13 @@ void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb, struct drm_clip_rect *rects, unsigned int num_rects);
-int vbox_framebuffer_init(struct drm_device *dev, +int vbox_framebuffer_init(struct vbox_private *vbox, struct vbox_framebuffer *vbox_fb, const struct DRM_MODE_FB_CMD *mode_cmd, struct drm_gem_object *obj);
-int vbox_fbdev_init(struct drm_device *dev); -void vbox_fbdev_fini(struct drm_device *dev); +int vbox_fbdev_init(struct vbox_private *vbox); +void vbox_fbdev_fini(struct vbox_private *vbox); void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr);
struct vbox_bo { @@ -234,10 +235,10 @@ int vbox_dumb_mmap_offset(struct drm_file *file, int vbox_mm_init(struct vbox_private *vbox); void vbox_mm_fini(struct vbox_private *vbox);
-int vbox_bo_create(struct drm_device *dev, int size, int align, +int vbox_bo_create(struct vbox_private *vbox, int size, int align, u32 flags, struct vbox_bo **pvboxbo);
-int vbox_gem_create(struct drm_device *dev, +int vbox_gem_create(struct vbox_private *vbox, u32 size, bool iskernel, struct drm_gem_object **obj);
int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr); diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index 79814117e063..11b6364ed14a 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -71,7 +71,9 @@ static int vboxfb_create(struct drm_fb_helper *helper, { struct vbox_fbdev *fbdev = container_of(helper, struct vbox_fbdev, helper); - struct drm_device *dev = fbdev->helper.dev; + struct vbox_private *vbox = container_of(fbdev->helper.dev, + struct vbox_private, ddev); + struct pci_dev *pdev = vbox->ddev.pdev; struct DRM_MODE_FB_CMD mode_cmd; struct drm_framebuffer *fb; struct fb_info *info; @@ -89,13 +91,13 @@ static int vboxfb_create(struct drm_fb_helper *helper,
size = pitch * mode_cmd.height;
- ret = vbox_gem_create(fbdev->helper.dev, size, true, &gobj); + ret = vbox_gem_create(vbox, size, true, &gobj); if (ret) { DRM_ERROR("failed to create fbcon backing object %d\n", ret); return ret; }
- ret = vbox_framebuffer_init(dev, &fbdev->afb, &mode_cmd, gobj); + ret = vbox_framebuffer_init(vbox, &fbdev->afb, &mode_cmd, gobj); if (ret) return ret;
@@ -143,8 +145,8 @@ static int vboxfb_create(struct drm_fb_helper *helper, * This seems to be done for safety checking that the framebuffer * is not registered twice by different drivers. */ - info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0); - info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); + info->apertures->ranges[0].base = pci_resource_start(pdev, 0); + info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width, @@ -169,9 +171,8 @@ static struct drm_fb_helper_funcs vbox_fb_helper_funcs = { .fb_probe = vboxfb_create, };
-void vbox_fbdev_fini(struct drm_device *dev) +void vbox_fbdev_fini(struct vbox_private *vbox) { - struct vbox_private *vbox = dev->dev_private; struct vbox_fbdev *fbdev = vbox->fbdev; struct vbox_framebuffer *afb = &fbdev->afb;
@@ -205,9 +206,9 @@ void vbox_fbdev_fini(struct drm_device *dev) drm_framebuffer_cleanup(&afb->base); }
-int vbox_fbdev_init(struct drm_device *dev) +int vbox_fbdev_init(struct vbox_private *vbox) { - struct vbox_private *vbox = dev->dev_private; + struct drm_device *dev = &vbox->ddev; struct vbox_fbdev *fbdev; int ret;
diff --git a/drivers/staging/vboxvideo/vbox_irq.c b/drivers/staging/vboxvideo/vbox_irq.c index 74abdf02d9fd..09f858ec1369 100644 --- a/drivers/staging/vboxvideo/vbox_irq.c +++ b/drivers/staging/vboxvideo/vbox_irq.c @@ -123,7 +123,7 @@ static void validate_or_set_position_hints(struct vbox_private *vbox) */ static void vbox_update_mode_hints(struct vbox_private *vbox) { - struct drm_device *dev = vbox->dev; + struct drm_device *dev = &vbox->ddev; struct drm_connector *connector; struct vbox_connector *vbox_conn; struct vbva_modehint *hints; @@ -179,7 +179,7 @@ static void vbox_hotplug_worker(struct work_struct *work) hotplug_work);
vbox_update_mode_hints(vbox); - drm_kms_helper_hotplug_event(vbox->dev); + drm_kms_helper_hotplug_event(&vbox->ddev); }
int vbox_irq_init(struct vbox_private *vbox) @@ -187,11 +187,11 @@ int vbox_irq_init(struct vbox_private *vbox) INIT_WORK(&vbox->hotplug_work, vbox_hotplug_worker); vbox_update_mode_hints(vbox);
- return drm_irq_install(vbox->dev, vbox->dev->pdev->irq); + return drm_irq_install(&vbox->ddev, vbox->ddev.pdev->irq); }
void vbox_irq_fini(struct vbox_private *vbox) { - drm_irq_uninstall(vbox->dev); + drm_irq_uninstall(&vbox->ddev); flush_work(&vbox->hotplug_work); } diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c index 815292f1d7e6..95100c5976e4 100644 --- a/drivers/staging/vboxvideo/vbox_main.c +++ b/drivers/staging/vboxvideo/vbox_main.c @@ -155,16 +155,16 @@ static const struct drm_framebuffer_funcs vbox_fb_funcs = { .dirty = vbox_user_framebuffer_dirty, };
-int vbox_framebuffer_init(struct drm_device *dev, +int vbox_framebuffer_init(struct vbox_private *vbox, struct vbox_framebuffer *vbox_fb, const struct DRM_MODE_FB_CMD *mode_cmd, struct drm_gem_object *obj) { int ret;
- drm_helper_mode_fill_fb_struct(dev, &vbox_fb->base, mode_cmd); + drm_helper_mode_fill_fb_struct(&vbox->ddev, &vbox_fb->base, mode_cmd); vbox_fb->obj = obj; - ret = drm_framebuffer_init(dev, &vbox_fb->base, &vbox_fb_funcs); + ret = drm_framebuffer_init(&vbox->ddev, &vbox_fb->base, &vbox_fb_funcs); if (ret) { DRM_ERROR("framebuffer init failed %d\n", ret); return ret; @@ -177,7 +177,7 @@ static int vbox_accel_init(struct vbox_private *vbox) { unsigned int i;
- vbox->vbva_info = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs, + vbox->vbva_info = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs, sizeof(*vbox->vbva_info), GFP_KERNEL); if (!vbox->vbva_info) return -ENOMEM; @@ -185,7 +185,7 @@ static int vbox_accel_init(struct vbox_private *vbox) /* Take a command buffer for each screen from the end of usable VRAM. */ vbox->available_vram_size -= vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE;
- vbox->vbva_buffers = pci_iomap_range(vbox->dev->pdev, 0, + vbox->vbva_buffers = pci_iomap_range(vbox->ddev.pdev, 0, vbox->available_vram_size, vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE); @@ -204,7 +204,7 @@ static int vbox_accel_init(struct vbox_private *vbox) static void vbox_accel_fini(struct vbox_private *vbox) { vbox_disable_accel(vbox); - pci_iounmap(vbox->dev->pdev, vbox->vbva_buffers); + pci_iounmap(vbox->ddev.pdev, vbox->vbva_buffers); }
/** Do we support the 4.3 plus mode hint reporting interface? */ @@ -253,7 +253,7 @@ int vbox_hw_init(struct vbox_private *vbox)
/* Map guest-heap at end of vram */ vbox->guest_heap = - pci_iomap_range(vbox->dev->pdev, 0, GUEST_HEAP_OFFSET(vbox), + pci_iomap_range(vbox->ddev.pdev, 0, GUEST_HEAP_OFFSET(vbox), GUEST_HEAP_SIZE); if (!vbox->guest_heap) return -ENOMEM; @@ -288,7 +288,7 @@ int vbox_hw_init(struct vbox_private *vbox) goto err_destroy_guest_pool; }
- vbox->last_mode_hints = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs, + vbox->last_mode_hints = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs, sizeof(struct vbva_modehint), GFP_KERNEL); if (!vbox->last_mode_hints) { @@ -305,7 +305,7 @@ int vbox_hw_init(struct vbox_private *vbox) err_destroy_guest_pool: gen_pool_destroy(vbox->guest_pool); err_unmap_guest_heap: - pci_iounmap(vbox->dev->pdev, vbox->guest_heap); + pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); return ret; }
@@ -313,7 +313,7 @@ void vbox_hw_fini(struct vbox_private *vbox) { vbox_accel_fini(vbox); gen_pool_destroy(vbox->guest_pool); - pci_iounmap(vbox->dev->pdev, vbox->guest_heap); + pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); }
/** @@ -328,7 +328,7 @@ void vbox_driver_lastclose(struct drm_device *dev) drm_fb_helper_restore_fbdev_mode_unlocked(&vbox->fbdev->helper); }
-int vbox_gem_create(struct drm_device *dev, +int vbox_gem_create(struct vbox_private *vbox, u32 size, bool iskernel, struct drm_gem_object **obj) { struct vbox_bo *vboxbo; @@ -340,7 +340,7 @@ int vbox_gem_create(struct drm_device *dev, if (size == 0) return -EINVAL;
- ret = vbox_bo_create(dev, size, 0, 0, &vboxbo); + ret = vbox_bo_create(vbox, size, 0, 0, &vboxbo); if (ret) { if (ret != -ERESTARTSYS) DRM_ERROR("failed to allocate GEM object\n"); @@ -355,14 +355,16 @@ int vbox_gem_create(struct drm_device *dev, int vbox_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args) { - int ret; + struct vbox_private *vbox = + container_of(dev, struct vbox_private, ddev); struct drm_gem_object *gobj; u32 handle; + int ret;
args->pitch = args->width * ((args->bpp + 7) / 8); args->size = args->pitch * args->height;
- ret = vbox_gem_create(dev, args->size, false, &gobj); + ret = vbox_gem_create(vbox, args->size, false, &gobj); if (ret) return ret;
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 2587e6aecca2..13696ba19c4f 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -179,7 +179,7 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox) * If so then screen layout can be deduced from the crtc offsets. * Same fall-back if this is the fbdev frame-buffer. */ - list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) { + list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) { if (!fb1) { fb1 = CRTC_FB(crtci); if (to_vbox_framebuffer(fb1) == &vbox->fbdev->afb) @@ -189,7 +189,7 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox) } } if (single_framebuffer) { - list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, + list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) { if (to_vbox_crtc(crtci)->crtc_id != 0) continue; @@ -202,7 +202,7 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox) } } /* Otherwise calculate the total span of all screens. */ - list_for_each_entry(connectori, &vbox->dev->mode_config.connector_list, + list_for_each_entry(connectori, &vbox->ddev.mode_config.connector_list, head) { struct vbox_connector *vbox_connector = to_vbox_connector(connectori); @@ -285,7 +285,7 @@ static int vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, if (mode && vbox_set_up_input_mapping(vbox)) { struct drm_crtc *crtci;
- list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, + list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) { if (crtci == crtc) continue; @@ -324,8 +324,6 @@ static int vbox_crtc_page_flip(struct drm_crtc *crtc, uint32_t page_flip_flags, struct drm_modeset_acquire_ctx *ctx) { - struct vbox_private *vbox = crtc->dev->dev_private; - struct drm_device *drm = vbox->dev; unsigned long flags; int rc;
@@ -333,12 +331,12 @@ static int vbox_crtc_page_flip(struct drm_crtc *crtc, if (rc) return rc;
- spin_lock_irqsave(&drm->event_lock, flags); + spin_lock_irqsave(&crtc->dev->event_lock, flags);
if (event) drm_crtc_send_vblank_event(crtc, event);
- spin_unlock_irqrestore(&drm->event_lock, flags); + spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
return 0; } @@ -593,19 +591,19 @@ static int vbox_get_modes(struct drm_connector *connector)
if (vbox_connector->vbox_crtc->x_hint != -1) drm_object_property_set_value(&connector->base, - vbox->dev->mode_config.suggested_x_property, + vbox->ddev.mode_config.suggested_x_property, vbox_connector->vbox_crtc->x_hint); else drm_object_property_set_value(&connector->base, - vbox->dev->mode_config.suggested_x_property, 0); + vbox->ddev.mode_config.suggested_x_property, 0);
if (vbox_connector->vbox_crtc->y_hint != -1) drm_object_property_set_value(&connector->base, - vbox->dev->mode_config.suggested_y_property, + vbox->ddev.mode_config.suggested_y_property, vbox_connector->vbox_crtc->y_hint); else drm_object_property_set_value(&connector->base, - vbox->dev->mode_config.suggested_y_property, 0); + vbox->ddev.mode_config.suggested_y_property, 0);
return num_modes; } @@ -701,6 +699,8 @@ static struct drm_framebuffer *vbox_user_framebuffer_create( struct drm_file *filp, const struct drm_mode_fb_cmd2 *mode_cmd) { + struct vbox_private *vbox = + container_of(dev, struct vbox_private, ddev); struct drm_gem_object *obj; struct vbox_framebuffer *vbox_fb; int ret = -ENOMEM; @@ -713,7 +713,7 @@ static struct drm_framebuffer *vbox_user_framebuffer_create( if (!vbox_fb) goto err_unref_obj;
- ret = vbox_framebuffer_init(dev, vbox_fb, mode_cmd, obj); + ret = vbox_framebuffer_init(vbox, vbox_fb, mode_cmd, obj); if (ret) goto err_free_vbox_fb;
@@ -730,9 +730,9 @@ static const struct drm_mode_config_funcs vbox_mode_funcs = { .fb_create = vbox_user_framebuffer_create, };
-int vbox_mode_init(struct drm_device *dev) +int vbox_mode_init(struct vbox_private *vbox) { - struct vbox_private *vbox = dev->dev_private; + struct drm_device *dev = &vbox->ddev; struct drm_encoder *encoder; struct vbox_crtc *vbox_crtc; unsigned int i; @@ -771,9 +771,9 @@ int vbox_mode_init(struct drm_device *dev) return ret; }
-void vbox_mode_fini(struct drm_device *dev) +void vbox_mode_fini(struct vbox_private *vbox) { - drm_mode_config_cleanup(dev); + drm_mode_config_cleanup(&vbox->ddev); /* vbox_cursor_fini(dev); */ }
@@ -824,7 +824,7 @@ static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
/* Hide cursor. */ vbox_crtc->cursor_enabled = false; - list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, + list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) { if (to_vbox_crtc(crtci)->cursor_enabled) cursor_enabled = true; diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c index 548edb7c494b..7b8eac30faca 100644 --- a/drivers/staging/vboxvideo/vbox_ttm.c +++ b/drivers/staging/vboxvideo/vbox_ttm.c @@ -169,7 +169,7 @@ static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev, return 0; case TTM_PL_VRAM: mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = pci_resource_start(vbox->dev->pdev, 0); + mem->bus.base = pci_resource_start(vbox->ddev.pdev, 0); mem->bus.is_iomem = true; break; default: @@ -224,7 +224,7 @@ static struct ttm_bo_driver vbox_bo_driver = { int vbox_mm_init(struct vbox_private *vbox) { int ret; - struct drm_device *dev = vbox->dev; + struct drm_device *dev = &vbox->ddev; struct ttm_bo_device *bdev = &vbox->ttm.bdev;
ret = vbox_ttm_global_init(vbox); @@ -269,8 +269,8 @@ void vbox_mm_fini(struct vbox_private *vbox) { #ifdef DRM_MTRR_WC drm_mtrr_del(vbox->fb_mtrr, - pci_resource_start(vbox->dev->pdev, 0), - pci_resource_len(vbox->dev->pdev, 0), DRM_MTRR_WC); + pci_resource_start(vbox->ddev.pdev, 0), + pci_resource_len(vbox->ddev.pdev, 0), DRM_MTRR_WC); #else arch_phys_wc_del(vbox->fb_mtrr); #endif @@ -305,10 +305,9 @@ void vbox_ttm_placement(struct vbox_bo *bo, int domain) } }
-int vbox_bo_create(struct drm_device *dev, int size, int align, +int vbox_bo_create(struct vbox_private *vbox, int size, int align, u32 flags, struct vbox_bo **pvboxbo) { - struct vbox_private *vbox = dev->dev_private; struct vbox_bo *vboxbo; size_t acc_size; int ret; @@ -317,7 +316,7 @@ int vbox_bo_create(struct drm_device *dev, int size, int align, if (!vboxbo) return -ENOMEM;
- ret = drm_gem_object_init(dev, &vboxbo->gem, size); + ret = drm_gem_object_init(&vbox->ddev, &vboxbo->gem, size); if (ret) goto err_free_vboxbo;
vbox_pm_resume() is the only caller of vbox_drm_resume(), so squash the 2 functions into 1.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_drv.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c index c4290d4b4a53..c6a53b0ad66c 100644 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ b/drivers/staging/vboxvideo/vbox_drv.c @@ -152,22 +152,6 @@ static int vbox_drm_thaw(struct vbox_private *vbox) return 0; }
-static int vbox_drm_resume(struct vbox_private *vbox) -{ - int ret; - - if (pci_enable_device(vbox->ddev.pdev)) - return -EIO; - - ret = vbox_drm_thaw(vbox); - if (ret) - return ret; - - drm_kms_helper_poll_enable(&vbox->ddev); - - return 0; -} - static int vbox_pm_suspend(struct device *dev) { struct vbox_private *vbox = dev_get_drvdata(dev); @@ -186,8 +170,18 @@ static int vbox_pm_suspend(struct device *dev) static int vbox_pm_resume(struct device *dev) { struct vbox_private *vbox = dev_get_drvdata(dev); + int ret;
- return vbox_drm_resume(vbox); + if (pci_enable_device(vbox->ddev.pdev)) + return -EIO; + + ret = vbox_drm_thaw(vbox); + if (ret) + return ret; + + drm_kms_helper_poll_enable(&vbox->ddev); + + return 0; }
static int vbox_pm_freeze(struct device *dev)
Allow specifying where to pin the framebuffer bo, so that this helper can be used from the cursor code too.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_mode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 13696ba19c4f..3beae9d65a09 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -221,7 +221,7 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox) return old_single_framebuffer != vbox->single_framebuffer; }
-static int vbox_fb_pin(struct drm_framebuffer *fb, u64 *addr) +static int vbox_fb_pin(struct drm_framebuffer *fb, u32 pl_flag, u64 *addr) { struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj); int ret; @@ -230,7 +230,7 @@ static int vbox_fb_pin(struct drm_framebuffer *fb, u64 *addr) if (ret) return ret;
- ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, addr); + ret = vbox_bo_pin(bo, pl_flag, addr); vbox_bo_unreserve(bo); return ret; } @@ -267,7 +267,7 @@ static int vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, int ret;
/* Prepare: pin the new framebuffer bo */ - ret = vbox_fb_pin(new_fb, &gpu_addr); + ret = vbox_fb_pin(new_fb, TTM_PL_FLAG_VRAM, &gpu_addr); if (ret) { DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret); return ret;
Let's expose the primary plane initialization inside the vboxvideo driver in preparation for universal planes and atomic.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_mode.c | 78 +++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 3beae9d65a09..f35045ce154b 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -382,21 +382,91 @@ static const struct drm_crtc_funcs vbox_crtc_funcs = { .destroy = vbox_crtc_destroy, };
+static const uint32_t vbox_primary_plane_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, +}; + +static const struct drm_plane_funcs vbox_primary_plane_funcs = { + .update_plane = drm_primary_helper_update, + .disable_plane = drm_primary_helper_disable, + .destroy = drm_primary_helper_destroy, +}; + +static struct drm_plane *vbox_create_plane(struct vbox_private *vbox, + unsigned int possible_crtcs, + enum drm_plane_type type) +{ + const struct drm_plane_helper_funcs *helper_funcs = NULL; + const struct drm_plane_funcs *funcs; + struct drm_plane *plane; + const uint32_t *formats; + int num_formats; + int err; + + if (type == DRM_PLANE_TYPE_PRIMARY) { + funcs = &vbox_primary_plane_funcs; + formats = vbox_primary_plane_formats; + num_formats = ARRAY_SIZE(vbox_primary_plane_formats); + } else { + return ERR_PTR(-EINVAL); + } + + plane = kzalloc(sizeof(*plane), GFP_KERNEL); + if (!plane) + return ERR_PTR(-ENOMEM); + + err = drm_universal_plane_init(&vbox->ddev, plane, possible_crtcs, + funcs, formats, num_formats, + NULL, type, NULL); + if (err) + goto free_plane; + + drm_plane_helper_add(plane, helper_funcs); + + return plane; + +free_plane: + kfree(plane); + return ERR_PTR(-EINVAL); +} + static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i) { + struct vbox_private *vbox = + container_of(dev, struct vbox_private, ddev); struct vbox_crtc *vbox_crtc; + struct drm_plane *primary; + int ret;
vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL); if (!vbox_crtc) - return NULL; + return ERR_PTR(-ENOMEM); + + primary = vbox_create_plane(vbox, 1 << i, DRM_PLANE_TYPE_PRIMARY); + if (IS_ERR(primary)) { + ret = PTR_ERR(primary); + goto free_mem; + }
vbox_crtc->crtc_id = i;
- drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs); + ret = drm_crtc_init_with_planes(dev, &vbox_crtc->base, primary, NULL, + &vbox_crtc_funcs, NULL); + if (ret) + goto clean_primary; + drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256); drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
return vbox_crtc; + +clean_primary: + drm_plane_cleanup(primary); + kfree(primary); +free_mem: + kfree(vbox_crtc); + return ERR_PTR(ret); }
static void vbox_encoder_destroy(struct drm_encoder *encoder) @@ -750,8 +820,8 @@ int vbox_mode_init(struct vbox_private *vbox) /* vbox_cursor_init(dev); */ for (i = 0; i < vbox->num_crtcs; ++i) { vbox_crtc = vbox_crtc_init(dev, i); - if (!vbox_crtc) { - ret = -ENOMEM; + if (IS_ERR(vbox_crtc)) { + ret = PTR_ERR(vbox_crtc); goto err_drm_mode_cleanup; } encoder = vbox_encoder_init(dev, i);
The fbdev compat fb gets pinned into VRAM at creation and then gets pinned a second time when set as scanout buffer and unpinned when replaced, this means its pin count never becomes less then 1, so it is always at the same address and there is no need for the vbox_fbdev_set_base() call.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_drv.h | 1 - drivers/staging/vboxvideo/vbox_fb.c | 14 +++++--------- drivers/staging/vboxvideo/vbox_mode.c | 3 --- 3 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h index 28ffdffe877a..5034c6bd5445 100644 --- a/drivers/staging/vboxvideo/vbox_drv.h +++ b/drivers/staging/vboxvideo/vbox_drv.h @@ -201,7 +201,6 @@ int vbox_framebuffer_init(struct vbox_private *vbox,
int vbox_fbdev_init(struct vbox_private *vbox); void vbox_fbdev_fini(struct vbox_private *vbox); -void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr);
struct vbox_bo { struct ttm_buffer_object bo; diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index 11b6364ed14a..0e5550fa7c57 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -80,6 +80,7 @@ static int vboxfb_create(struct drm_fb_helper *helper, struct drm_gem_object *gobj; struct vbox_bo *bo; int size, ret; + u64 gpu_addr; u32 pitch;
mode_cmd.width = sizes->surface_width; @@ -107,7 +108,7 @@ static int vboxfb_create(struct drm_fb_helper *helper, if (ret) return ret;
- ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL); + ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); if (ret) { vbox_bo_unreserve(bo); return ret; @@ -152,6 +153,9 @@ static int vboxfb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width, sizes->fb_height);
+ info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr; + info->fix.smem_len = vbox->available_vram_size - gpu_addr; + info->screen_base = (char __iomem *)bo->kmap.virtual; info->screen_size = size;
@@ -241,11 +245,3 @@ int vbox_fbdev_init(struct vbox_private *vbox) drm_fb_helper_fini(&fbdev->helper); return ret; } - -void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr) -{ - struct fb_info *fbdev = vbox->fbdev->helper.fbdev; - - fbdev->fix.smem_start = fbdev->apertures->ranges[0].base + gpu_addr; - fbdev->fix.smem_len = vbox->available_vram_size - gpu_addr; -} diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index f35045ce154b..6d7a89524fbf 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -276,9 +276,6 @@ static int vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, /* Commit: Update hardware to use the new fb */ mutex_lock(&vbox->hw_mutex);
- if (&vbox->fbdev->afb == to_vbox_framebuffer(new_fb)) - vbox_fbdev_set_base(vbox, gpu_addr); - vbox_crtc->fb_offset = gpu_addr;
/* vbox_do_modeset() checks vbox->single_framebuffer so update it now */
Move pin / unpin of fb out of vbox_crtc_set_base_and_mode() so that it can be used to implement the atomic_update drm_plane_helper_func for the primary plane.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_drv.h | 5 +++ drivers/staging/vboxvideo/vbox_mode.c | 52 ++++++++++++++------------- drivers/staging/vboxvideo/vbox_ttm.c | 5 --- 3 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h index 5034c6bd5445..6a4d3b382e79 100644 --- a/drivers/staging/vboxvideo/vbox_drv.h +++ b/drivers/staging/vboxvideo/vbox_drv.h @@ -220,6 +220,11 @@ static inline struct vbox_bo *vbox_bo(struct ttm_buffer_object *bo)
#define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base)
+static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo) +{ + return bo->bo.offset; +} + int vbox_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 6d7a89524fbf..1a2416a59fe0 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -255,28 +255,18 @@ static void vbox_fb_unpin(struct drm_framebuffer *fb) vbox_bo_unreserve(bo); }
-static int vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, - struct drm_framebuffer *old_fb, - struct drm_framebuffer *new_fb, - struct drm_display_mode *mode, - int x, int y) +static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_display_mode *mode, + int x, int y) { + struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj); struct vbox_private *vbox = crtc->dev->dev_private; struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); - u64 gpu_addr; - int ret; - - /* Prepare: pin the new framebuffer bo */ - ret = vbox_fb_pin(new_fb, TTM_PL_FLAG_VRAM, &gpu_addr); - if (ret) { - DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret); - return ret; - }
- /* Commit: Update hardware to use the new fb */ mutex_lock(&vbox->hw_mutex);
- vbox_crtc->fb_offset = gpu_addr; + vbox_crtc->fb_offset = vbox_bo_gpu_offset(bo);
/* vbox_do_modeset() checks vbox->single_framebuffer so update it now */ if (mode && vbox_set_up_input_mapping(vbox)) { @@ -299,11 +289,6 @@ static int vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, vbox->input_mapping_height);
mutex_unlock(&vbox->hw_mutex); - - /* Cleanup: unpin the old fb */ - vbox_fb_unpin(old_fb); - - return 0; }
static int vbox_crtc_mode_set(struct drm_crtc *crtc, @@ -311,8 +296,19 @@ static int vbox_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *old_fb) { - return vbox_crtc_set_base_and_mode(crtc, old_fb, CRTC_FB(crtc), - mode, x, y); + int ret; + + ret = vbox_fb_pin(CRTC_FB(crtc), TTM_PL_FLAG_VRAM, NULL); + if (ret) { + DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret); + return ret; + } + + vbox_crtc_set_base_and_mode(crtc, CRTC_FB(crtc), mode, x, y); + + vbox_fb_unpin(old_fb); + + return 0; }
static int vbox_crtc_page_flip(struct drm_crtc *crtc, @@ -324,9 +320,15 @@ static int vbox_crtc_page_flip(struct drm_crtc *crtc, unsigned long flags; int rc;
- rc = vbox_crtc_set_base_and_mode(crtc, CRTC_FB(crtc), fb, NULL, 0, 0); - if (rc) + rc = vbox_fb_pin(fb, TTM_PL_FLAG_VRAM, NULL); + if (rc) { + DRM_WARN("Error %d pinning new fb, out of video mem?\n", rc); return rc; + } + + vbox_crtc_set_base_and_mode(crtc, fb, NULL, 0, 0); + + vbox_fb_unpin(CRTC_FB(crtc));
spin_lock_irqsave(&crtc->dev->event_lock, flags);
diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c index 7b8eac30faca..0e14556dcd6b 100644 --- a/drivers/staging/vboxvideo/vbox_ttm.c +++ b/drivers/staging/vboxvideo/vbox_ttm.c @@ -343,11 +343,6 @@ int vbox_bo_create(struct vbox_private *vbox, int size, int align, return ret; }
-static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo) -{ - return bo->bo.offset; -} - int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr) { struct ttm_operation_ctx ctx = { false, false };
When vbox_set_up_input_mapping() gets called the first crtc might be disable and not have a fb at all, triggering a NUL ptr deref at:
vbox->input_mapping_width = CRTC_FB(crtci)->width;
Instead of using the fb from the crtc with id 0, just use the fb from the first crtc with a fb. This is in the single_framebuffer = true path, so all crtc-s point to the same fb anyways.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_mode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 1a2416a59fe0..910ea19931c9 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -189,17 +189,17 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox) } } if (single_framebuffer) { + vbox->single_framebuffer = true; list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) { - if (to_vbox_crtc(crtci)->crtc_id != 0) + if (!CRTC_FB(crtci)) continue;
- vbox->single_framebuffer = true; vbox->input_mapping_width = CRTC_FB(crtci)->width; vbox->input_mapping_height = CRTC_FB(crtci)->height; - return old_single_framebuffer != - vbox->single_framebuffer; + break; } + return old_single_framebuffer != vbox->single_framebuffer; } /* Otherwise calculate the total span of all screens. */ list_for_each_entry(connectori, &vbox->ddev.mode_config.connector_list,
We always need to reserve the bo around a pin / unpin, so move the reservation there.
This allows removing the vbox_fb_[un]pin helpers.
Note this means that we now no longer hold the bo reserved while k[un]mapping it in vbox_fb.c this is fine as it is not necessary to hold it reserved for this.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_drv.h | 2 +- drivers/staging/vboxvideo/vbox_fb.c | 27 ++++---------- drivers/staging/vboxvideo/vbox_mode.c | 54 ++++++++------------------- drivers/staging/vboxvideo/vbox_ttm.c | 32 +++++++++------- 4 files changed, 42 insertions(+), 73 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h index 6a4d3b382e79..fffde1713101 100644 --- a/drivers/staging/vboxvideo/vbox_drv.h +++ b/drivers/staging/vboxvideo/vbox_drv.h @@ -245,7 +245,7 @@ int vbox_bo_create(struct vbox_private *vbox, int size, int align, int vbox_gem_create(struct vbox_private *vbox, u32 size, bool iskernel, struct drm_gem_object **obj);
-int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr); +int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag); int vbox_bo_unpin(struct vbox_bo *bo);
static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait) diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index 0e5550fa7c57..bdc87d02ecc5 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -104,18 +104,11 @@ static int vboxfb_create(struct drm_fb_helper *helper,
bo = gem_to_vbox_bo(gobj);
- ret = vbox_bo_reserve(bo, false); + ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM); if (ret) return ret;
- ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - if (ret) { - vbox_bo_unreserve(bo); - return ret; - } - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - vbox_bo_unreserve(bo); if (ret) { DRM_ERROR("failed to kmap fbcon\n"); return ret; @@ -153,6 +146,7 @@ static int vboxfb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width, sizes->fb_height);
+ gpu_addr = vbox_bo_gpu_offset(bo); info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr; info->fix.smem_len = vbox->available_vram_size - gpu_addr;
@@ -190,17 +184,12 @@ void vbox_fbdev_fini(struct vbox_private *vbox) if (afb->obj) { struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
- if (!vbox_bo_reserve(bo, false)) { - if (bo->kmap.virtual) - ttm_bo_kunmap(&bo->kmap); - /* - * QXL does this, but is it really needed before - * freeing? - */ - if (bo->pin_count) - vbox_bo_unpin(bo); - vbox_bo_unreserve(bo); - } + if (bo->kmap.virtual) + ttm_bo_kunmap(&bo->kmap); + + if (bo->pin_count) + vbox_bo_unpin(bo); + drm_gem_object_put_unlocked(afb->obj); afb->obj = NULL; } diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 910ea19931c9..bef99664d030 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -221,40 +221,6 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox) return old_single_framebuffer != vbox->single_framebuffer; }
-static int vbox_fb_pin(struct drm_framebuffer *fb, u32 pl_flag, u64 *addr) -{ - struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj); - int ret; - - ret = vbox_bo_reserve(bo, false); - if (ret) - return ret; - - ret = vbox_bo_pin(bo, pl_flag, addr); - vbox_bo_unreserve(bo); - return ret; -} - -static void vbox_fb_unpin(struct drm_framebuffer *fb) -{ - struct vbox_bo *bo; - int ret; - - if (!fb) - return; - - bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj); - - ret = vbox_bo_reserve(bo, false); - if (ret) { - DRM_ERROR("Error %d reserving fb bo, leaving it pinned\n", ret); - return; - } - - vbox_bo_unpin(bo); - vbox_bo_unreserve(bo); -} - static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_display_mode *mode, @@ -296,17 +262,22 @@ static int vbox_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *old_fb) { + struct drm_framebuffer *new_fb = CRTC_FB(crtc); + struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(new_fb)->obj); int ret;
- ret = vbox_fb_pin(CRTC_FB(crtc), TTM_PL_FLAG_VRAM, NULL); + ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM); if (ret) { DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret); return ret; }
- vbox_crtc_set_base_and_mode(crtc, CRTC_FB(crtc), mode, x, y); + vbox_crtc_set_base_and_mode(crtc, new_fb, mode, x, y);
- vbox_fb_unpin(old_fb); + if (old_fb) { + bo = gem_to_vbox_bo(to_vbox_framebuffer(old_fb)->obj); + vbox_bo_unpin(bo); + }
return 0; } @@ -317,10 +288,12 @@ static int vbox_crtc_page_flip(struct drm_crtc *crtc, uint32_t page_flip_flags, struct drm_modeset_acquire_ctx *ctx) { + struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj); + struct drm_framebuffer *old_fb = CRTC_FB(crtc); unsigned long flags; int rc;
- rc = vbox_fb_pin(fb, TTM_PL_FLAG_VRAM, NULL); + rc = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM); if (rc) { DRM_WARN("Error %d pinning new fb, out of video mem?\n", rc); return rc; @@ -328,7 +301,10 @@ static int vbox_crtc_page_flip(struct drm_crtc *crtc,
vbox_crtc_set_base_and_mode(crtc, fb, NULL, 0, 0);
- vbox_fb_unpin(CRTC_FB(crtc)); + if (old_fb) { + bo = gem_to_vbox_bo(to_vbox_framebuffer(old_fb)->obj); + vbox_bo_unpin(bo); + }
spin_lock_irqsave(&crtc->dev->event_lock, flags);
diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c index 0e14556dcd6b..bd0a1603764e 100644 --- a/drivers/staging/vboxvideo/vbox_ttm.c +++ b/drivers/staging/vboxvideo/vbox_ttm.c @@ -343,34 +343,32 @@ int vbox_bo_create(struct vbox_private *vbox, int size, int align, return ret; }
-int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr) +int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag) { struct ttm_operation_ctx ctx = { false, false }; int i, ret;
if (bo->pin_count) { bo->pin_count++; - if (gpu_addr) - *gpu_addr = vbox_bo_gpu_offset(bo); - return 0; }
+ ret = vbox_bo_reserve(bo, false); + if (ret) + return ret; + vbox_ttm_placement(bo, pl_flag);
for (i = 0; i < bo->placement.num_placement; i++) bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - if (ret) - return ret; - - bo->pin_count = 1; + if (ret == 0) + bo->pin_count = 1;
- if (gpu_addr) - *gpu_addr = vbox_bo_gpu_offset(bo); + vbox_bo_unreserve(bo);
- return 0; + return ret; }
int vbox_bo_unpin(struct vbox_bo *bo) @@ -386,14 +384,20 @@ int vbox_bo_unpin(struct vbox_bo *bo) if (bo->pin_count) return 0;
+ ret = vbox_bo_reserve(bo, false); + if (ret) { + DRM_ERROR("Error %d reserving bo, leaving it pinned\n", ret); + return ret; + } + for (i = 0; i < bo->placement.num_placement; i++) bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - if (ret) - return ret;
- return 0; + vbox_bo_unreserve(bo); + + return ret; }
/*
Add vbox_bo_k[un]map helper functions instead of having code directly poking struct vbox_bo internals.
While touch neighboring code anyways also fix a return -PTR_ERR(info), which should be return PTR_ERR(info).
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/staging/vboxvideo/vbox_drv.h | 2 ++ drivers/staging/vboxvideo/vbox_fb.c | 19 +++++++------------ drivers/staging/vboxvideo/vbox_ttm.c | 28 +++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h index fffde1713101..6c52cbd9e91e 100644 --- a/drivers/staging/vboxvideo/vbox_drv.h +++ b/drivers/staging/vboxvideo/vbox_drv.h @@ -269,6 +269,8 @@ static inline void vbox_bo_unreserve(struct vbox_bo *bo) void vbox_ttm_placement(struct vbox_bo *bo, int domain); int vbox_bo_push_sysram(struct vbox_bo *bo); int vbox_mmap(struct file *filp, struct vm_area_struct *vma); +void *vbox_bo_kmap(struct vbox_bo *bo); +void vbox_bo_kunmap(struct vbox_bo *bo);
/* vbox_prime.c */ int vbox_gem_prime_pin(struct drm_gem_object *obj); diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index bdc87d02ecc5..b8b42f9aafae 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -108,15 +108,14 @@ static int vboxfb_create(struct drm_fb_helper *helper, if (ret) return ret;
- ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - if (ret) { - DRM_ERROR("failed to kmap fbcon\n"); - return ret; - } - info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) - return -PTR_ERR(info); + return PTR_ERR(info); + + info->screen_size = size; + info->screen_base = (char __iomem *)vbox_bo_kmap(bo); + if (IS_ERR(info->screen_base)) + return PTR_ERR(info->screen_base);
info->par = fbdev;
@@ -150,9 +149,6 @@ static int vboxfb_create(struct drm_fb_helper *helper, info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr; info->fix.smem_len = vbox->available_vram_size - gpu_addr;
- info->screen_base = (char __iomem *)bo->kmap.virtual; - info->screen_size = size; - #ifdef CONFIG_DRM_KMS_FB_HELPER info->fbdefio = &vbox_defio; fb_deferred_io_init(info); @@ -184,8 +180,7 @@ void vbox_fbdev_fini(struct vbox_private *vbox) if (afb->obj) { struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
- if (bo->kmap.virtual) - ttm_bo_kunmap(&bo->kmap); + vbox_bo_kunmap(bo);
if (bo->pin_count) vbox_bo_unpin(bo); diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c index bd0a1603764e..5ecfa7629173 100644 --- a/drivers/staging/vboxvideo/vbox_ttm.c +++ b/drivers/staging/vboxvideo/vbox_ttm.c @@ -418,8 +418,10 @@ int vbox_bo_push_sysram(struct vbox_bo *bo) if (bo->pin_count) return 0;
- if (bo->kmap.virtual) + if (bo->kmap.virtual) { ttm_bo_kunmap(&bo->kmap); + bo->kmap.virtual = NULL; + }
vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
@@ -448,3 +450,27 @@ int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev); } + +void *vbox_bo_kmap(struct vbox_bo *bo) +{ + int ret; + + if (bo->kmap.virtual) + return bo->kmap.virtual; + + ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); + if (ret) { + DRM_ERROR("Error kmapping bo: %d\n", ret); + return NULL; + } + + return bo->kmap.virtual; +} + +void vbox_bo_kunmap(struct vbox_bo *bo) +{ + if (bo->kmap.virtual) { + ttm_bo_kunmap(&bo->kmap); + bo->kmap.virtual = NULL; + } +}
dri-devel@lists.freedesktop.org