diff options
| author | Dave Airlie <airlied@redhat.com> | 2016-07-26 20:33:08 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2016-07-26 20:33:08 -0400 |
| commit | 9af07af948ff3a8e20920b9279821db244d1ca69 (patch) | |
| tree | b208a39aa6b33a24f46cf2bd5cbbd623f2f68bfb | |
| parent | 5e580523d9128a4d8364fe89d36c38fc7819c8dd (diff) | |
| parent | e8d3ef02787fc72996cfb423180dc79764c239fa (diff) | |
Merge tag 'topic/drm-misc-2016-07-22' of git://anongit.freedesktop.org/drm-intel into drm-next
Suddenly everyone shows up with their trivial patch series!
- piles of if (!ptr) check removals from Markus Elfring
- more of_node_put fixes from Peter Chen
- make fbdev support really optional in all drivers (except vmwgfx),
somehow this fell through the cracks when we did all the hard prep work
a while ago. Patches from Tobias Jakobi.
- leftover patches for the connector reg/unreg cleanup (required that I
backmerged drm-next) from Chris
- last vgem fence patch from Chris
- fix up warnings in the new sphinx gpu docs build
- misc other small bits
* tag 'topic/drm-misc-2016-07-22' of git://anongit.freedesktop.org/drm-intel: (57 commits)
GPU-DRM-Exynos: Delete an unnecessary check before the function call "vunmap"
GPU-DRM-sun4i: Delete an unnecessary check before drm_fbdev_cma_hotplug_event()
drm/atomic: Delete an unnecessary check before drm_property_unreference_blob()
drm/rockchip: analogix_dp: add missing clk_disable_unprepare() on error
drm: drm_connector->s/connector_id/index/ for consistency
drm/virtio: Fix non static symbol warning
drm/arc: Remove redundant dev_err call in arcpgu_load()
drm/arc: Fix some sparse warnings
drm/vgem: Fix non static symbol warning
drm/doc: Spinx leftovers
drm/dp-mst: Missing kernel doc
drm/dp-mst: Remove tx_down_in_progress
drm/doc: Fix missing kerneldoc for drm_dp_helper.c
drm: Extract&Document drm_irq.h
drm/doc: document all the properties in drm_mode_config
drm/drm-kms.rst: Remove unused drm_fourcc.h include directive
drm/doc: Add kerneldoc for @index
drm: Unexport drm_connector_unregister_all()
drm/sun4i: Remove redundant call to drm_connector_unregister_all()
drm/ttm: Delete an unnecessary check before the function call "ttm_tt_destroy"
...
55 files changed, 988 insertions, 361 deletions
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index 490d655cda20..3bb26135971f 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst | |||
| @@ -188,7 +188,8 @@ Manual IRQ Registration | |||
| 188 | Drivers that require multiple interrupt handlers can't use the managed | 188 | Drivers that require multiple interrupt handlers can't use the managed |
| 189 | IRQ registration functions. In that case IRQs must be registered and | 189 | IRQ registration functions. In that case IRQs must be registered and |
| 190 | unregistered manually (usually with the :c:func:`request_irq()` and | 190 | unregistered manually (usually with the :c:func:`request_irq()` and |
| 191 | :c:func:`free_irq()` functions, or their devm_\* equivalent). | 191 | :c:func:`free_irq()` functions, or their :c:func:`devm_request_irq()` and |
| 192 | :c:func:`devm_free_irq()` equivalents). | ||
| 192 | 193 | ||
| 193 | When manually registering IRQs, drivers must not set the | 194 | When manually registering IRQs, drivers must not set the |
| 194 | DRIVER_HAVE_IRQ driver feature flag, and must not provide the | 195 | DRIVER_HAVE_IRQ driver feature flag, and must not provide the |
| @@ -242,11 +243,13 @@ Open/Close, File Operations and IOCTLs | |||
| 242 | Open and Close | 243 | Open and Close |
| 243 | -------------- | 244 | -------------- |
| 244 | 245 | ||
| 245 | int (\*firstopen) (struct drm_device \*); void (\*lastclose) (struct | 246 | Open and close handlers. None of those methods are mandatory:: |
| 246 | drm_device \*); int (\*open) (struct drm_device \*, struct drm_file | 247 | |
| 247 | \*); void (\*preclose) (struct drm_device \*, struct drm_file \*); | 248 | int (*firstopen) (struct drm_device *); |
| 248 | void (\*postclose) (struct drm_device \*, struct drm_file \*); | 249 | void (*lastclose) (struct drm_device *); |
| 249 | Open and close handlers. None of those methods are mandatory. | 250 | int (*open) (struct drm_device *, struct drm_file *); |
| 251 | void (*preclose) (struct drm_device *, struct drm_file *); | ||
| 252 | void (*postclose) (struct drm_device *, struct drm_file *); | ||
| 250 | 253 | ||
| 251 | The firstopen method is called by the DRM core for legacy UMS (User Mode | 254 | The firstopen method is called by the DRM core for legacy UMS (User Mode |
| 252 | Setting) drivers only when an application opens a device that has no | 255 | Setting) drivers only when an application opens a device that has no |
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 0e1c80436c1d..8dfa4b214b96 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst | |||
| @@ -67,9 +67,6 @@ drivers can manually clean up a framebuffer at module unload time with | |||
| 67 | DRM Format Handling | 67 | DRM Format Handling |
| 68 | ------------------- | 68 | ------------------- |
| 69 | 69 | ||
| 70 | .. kernel-doc:: include/drm/drm_fourcc.h | ||
| 71 | :internal: | ||
| 72 | |||
| 73 | .. kernel-doc:: drivers/gpu/drm/drm_fourcc.c | 70 | .. kernel-doc:: drivers/gpu/drm/drm_fourcc.c |
| 74 | :export: | 71 | :export: |
| 75 | 72 | ||
| @@ -652,5 +649,5 @@ Vertical Blanking and Interrupt Handling Functions Reference | |||
| 652 | .. kernel-doc:: drivers/gpu/drm/drm_irq.c | 649 | .. kernel-doc:: drivers/gpu/drm/drm_irq.c |
| 653 | :export: | 650 | :export: |
| 654 | 651 | ||
| 655 | .. kernel-doc:: include/drm/drmP.h | 652 | .. kernel-doc:: include/drm/drm_irq.h |
| 656 | :functions: drm_crtc_vblank_waitqueue | 653 | :internal: |
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 20ce0687b111..ddaee60ae52a 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c | |||
| @@ -334,6 +334,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) | |||
| 334 | struct reservation_object *resv = exp_info->resv; | 334 | struct reservation_object *resv = exp_info->resv; |
| 335 | struct file *file; | 335 | struct file *file; |
| 336 | size_t alloc_size = sizeof(struct dma_buf); | 336 | size_t alloc_size = sizeof(struct dma_buf); |
| 337 | int ret; | ||
| 337 | 338 | ||
| 338 | if (!exp_info->resv) | 339 | if (!exp_info->resv) |
| 339 | alloc_size += sizeof(struct reservation_object); | 340 | alloc_size += sizeof(struct reservation_object); |
| @@ -357,8 +358,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) | |||
| 357 | 358 | ||
| 358 | dmabuf = kzalloc(alloc_size, GFP_KERNEL); | 359 | dmabuf = kzalloc(alloc_size, GFP_KERNEL); |
| 359 | if (!dmabuf) { | 360 | if (!dmabuf) { |
| 360 | module_put(exp_info->owner); | 361 | ret = -ENOMEM; |
| 361 | return ERR_PTR(-ENOMEM); | 362 | goto err_module; |
| 362 | } | 363 | } |
| 363 | 364 | ||
| 364 | dmabuf->priv = exp_info->priv; | 365 | dmabuf->priv = exp_info->priv; |
| @@ -379,8 +380,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) | |||
| 379 | file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, | 380 | file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, |
| 380 | exp_info->flags); | 381 | exp_info->flags); |
| 381 | if (IS_ERR(file)) { | 382 | if (IS_ERR(file)) { |
| 382 | kfree(dmabuf); | 383 | ret = PTR_ERR(file); |
| 383 | return ERR_CAST(file); | 384 | goto err_dmabuf; |
| 384 | } | 385 | } |
| 385 | 386 | ||
| 386 | file->f_mode |= FMODE_LSEEK; | 387 | file->f_mode |= FMODE_LSEEK; |
| @@ -394,6 +395,12 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) | |||
| 394 | mutex_unlock(&db_list.lock); | 395 | mutex_unlock(&db_list.lock); |
| 395 | 396 | ||
| 396 | return dmabuf; | 397 | return dmabuf; |
| 398 | |||
| 399 | err_dmabuf: | ||
| 400 | kfree(dmabuf); | ||
| 401 | err_module: | ||
| 402 | module_put(exp_info->owner); | ||
| 403 | return ERR_PTR(ret); | ||
| 397 | } | 404 | } |
| 398 | EXPORT_SYMBOL_GPL(dma_buf_export); | 405 | EXPORT_SYMBOL_GPL(dma_buf_export); |
| 399 | 406 | ||
diff --git a/drivers/gpu/drm/arc/Kconfig b/drivers/gpu/drm/arc/Kconfig index f9a13b658fea..f47d88ba4fa5 100644 --- a/drivers/gpu/drm/arc/Kconfig +++ b/drivers/gpu/drm/arc/Kconfig | |||
| @@ -2,7 +2,6 @@ config DRM_ARCPGU | |||
| 2 | tristate "ARC PGU" | 2 | tristate "ARC PGU" |
| 3 | depends on DRM && OF | 3 | depends on DRM && OF |
| 4 | select DRM_KMS_CMA_HELPER | 4 | select DRM_KMS_CMA_HELPER |
| 5 | select DRM_KMS_FB_HELPER | ||
| 6 | select DRM_KMS_HELPER | 5 | select DRM_KMS_HELPER |
| 7 | help | 6 | help |
| 8 | Choose this option if you have an ARC PGU controller. | 7 | Choose this option if you have an ARC PGU controller. |
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index ccbdadb108dc..6d4ff34737cb 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c | |||
| @@ -28,8 +28,7 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev) | |||
| 28 | { | 28 | { |
| 29 | struct arcpgu_drm_private *arcpgu = dev->dev_private; | 29 | struct arcpgu_drm_private *arcpgu = dev->dev_private; |
| 30 | 30 | ||
| 31 | if (arcpgu->fbdev) | 31 | drm_fbdev_cma_hotplug_event(arcpgu->fbdev); |
| 32 | drm_fbdev_cma_hotplug_event(arcpgu->fbdev); | ||
| 33 | } | 32 | } |
| 34 | 33 | ||
| 35 | static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { | 34 | static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { |
| @@ -49,7 +48,7 @@ static void arcpgu_setup_mode_config(struct drm_device *drm) | |||
| 49 | drm->mode_config.funcs = &arcpgu_drm_modecfg_funcs; | 48 | drm->mode_config.funcs = &arcpgu_drm_modecfg_funcs; |
| 50 | } | 49 | } |
| 51 | 50 | ||
| 52 | int arcpgu_gem_mmap(struct file *filp, struct vm_area_struct *vma) | 51 | static int arcpgu_gem_mmap(struct file *filp, struct vm_area_struct *vma) |
| 53 | { | 52 | { |
| 54 | int ret; | 53 | int ret; |
| 55 | 54 | ||
| @@ -104,10 +103,8 @@ static int arcpgu_load(struct drm_device *drm) | |||
| 104 | 103 | ||
| 105 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 104 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 106 | arcpgu->regs = devm_ioremap_resource(&pdev->dev, res); | 105 | arcpgu->regs = devm_ioremap_resource(&pdev->dev, res); |
| 107 | if (IS_ERR(arcpgu->regs)) { | 106 | if (IS_ERR(arcpgu->regs)) |
| 108 | dev_err(drm->dev, "Could not remap IO mem\n"); | ||
| 109 | return PTR_ERR(arcpgu->regs); | 107 | return PTR_ERR(arcpgu->regs); |
| 110 | } | ||
| 111 | 108 | ||
| 112 | dev_info(drm->dev, "arc_pgu ID: 0x%x\n", | 109 | dev_info(drm->dev, "arc_pgu ID: 0x%x\n", |
| 113 | arc_pgu_read(arcpgu, ARCPGU_REG_ID)); | 110 | arc_pgu_read(arcpgu, ARCPGU_REG_ID)); |
| @@ -127,10 +124,11 @@ static int arcpgu_load(struct drm_device *drm) | |||
| 127 | encoder_node = of_parse_phandle(drm->dev->of_node, "encoder-slave", 0); | 124 | encoder_node = of_parse_phandle(drm->dev->of_node, "encoder-slave", 0); |
| 128 | if (encoder_node) { | 125 | if (encoder_node) { |
| 129 | ret = arcpgu_drm_hdmi_init(drm, encoder_node); | 126 | ret = arcpgu_drm_hdmi_init(drm, encoder_node); |
| 127 | of_node_put(encoder_node); | ||
| 130 | if (ret < 0) | 128 | if (ret < 0) |
| 131 | return ret; | 129 | return ret; |
| 132 | } else { | 130 | } else { |
| 133 | ret = arcpgu_drm_sim_init(drm, 0); | 131 | ret = arcpgu_drm_sim_init(drm, NULL); |
| 134 | if (ret < 0) | 132 | if (ret < 0) |
| 135 | return ret; | 133 | return ret; |
| 136 | } | 134 | } |
| @@ -151,7 +149,7 @@ static int arcpgu_load(struct drm_device *drm) | |||
| 151 | return 0; | 149 | return 0; |
| 152 | } | 150 | } |
| 153 | 151 | ||
| 154 | int arcpgu_unload(struct drm_device *drm) | 152 | static int arcpgu_unload(struct drm_device *drm) |
| 155 | { | 153 | { |
| 156 | struct arcpgu_drm_private *arcpgu = drm->dev_private; | 154 | struct arcpgu_drm_private *arcpgu = drm->dev_private; |
| 157 | 155 | ||
diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig index 1b2906568a48..9a18e1bd57b4 100644 --- a/drivers/gpu/drm/arm/Kconfig +++ b/drivers/gpu/drm/arm/Kconfig | |||
| @@ -9,7 +9,6 @@ config DRM_HDLCD | |||
| 9 | depends on COMMON_CLK | 9 | depends on COMMON_CLK |
| 10 | select DRM_ARM | 10 | select DRM_ARM |
| 11 | select DRM_KMS_HELPER | 11 | select DRM_KMS_HELPER |
| 12 | select DRM_KMS_FB_HELPER | ||
| 13 | select DRM_KMS_CMA_HELPER | 12 | select DRM_KMS_CMA_HELPER |
| 14 | help | 13 | help |
| 15 | Choose this option if you have an ARM High Definition Colour LCD | 14 | Choose this option if you have an ARM High Definition Colour LCD |
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 74279be20b75..d83b46a30327 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c | |||
| @@ -102,8 +102,7 @@ static void hdlcd_fb_output_poll_changed(struct drm_device *drm) | |||
| 102 | { | 102 | { |
| 103 | struct hdlcd_drm_private *hdlcd = drm->dev_private; | 103 | struct hdlcd_drm_private *hdlcd = drm->dev_private; |
| 104 | 104 | ||
| 105 | if (hdlcd->fbdev) | 105 | drm_fbdev_cma_hotplug_event(hdlcd->fbdev); |
| 106 | drm_fbdev_cma_hotplug_event(hdlcd->fbdev); | ||
| 107 | } | 106 | } |
| 108 | 107 | ||
| 109 | static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = { | 108 | static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = { |
diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig index eb773e9af313..15f3ecfb16f1 100644 --- a/drivers/gpu/drm/armada/Kconfig +++ b/drivers/gpu/drm/armada/Kconfig | |||
| @@ -1,11 +1,7 @@ | |||
| 1 | config DRM_ARMADA | 1 | config DRM_ARMADA |
| 2 | tristate "DRM support for Marvell Armada SoCs" | 2 | tristate "DRM support for Marvell Armada SoCs" |
| 3 | depends on DRM && HAVE_CLK && ARM | 3 | depends on DRM && HAVE_CLK && ARM |
| 4 | select FB_CFB_FILLRECT | ||
| 5 | select FB_CFB_COPYAREA | ||
| 6 | select FB_CFB_IMAGEBLIT | ||
| 7 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 8 | select DRM_KMS_FB_HELPER | ||
| 9 | help | 5 | help |
| 10 | Support the "LCD" controllers found on the Marvell Armada 510 | 6 | Support the "LCD" controllers found on the Marvell Armada 510 |
| 11 | devices. There are two controllers on the device, each controller | 7 | devices. There are two controllers on the device, each controller |
diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig index 8a784c460c89..15f6ce7acb2a 100644 --- a/drivers/gpu/drm/ast/Kconfig +++ b/drivers/gpu/drm/ast/Kconfig | |||
| @@ -2,11 +2,7 @@ config DRM_AST | |||
| 2 | tristate "AST server chips" | 2 | tristate "AST server chips" |
| 3 | depends on DRM && PCI | 3 | depends on DRM && PCI |
| 4 | select DRM_TTM | 4 | select DRM_TTM |
| 5 | select FB_SYS_COPYAREA | ||
| 6 | select FB_SYS_FILLRECT | ||
| 7 | select FB_SYS_IMAGEBLIT | ||
| 8 | select DRM_KMS_HELPER | 5 | select DRM_KMS_HELPER |
| 9 | select DRM_KMS_FB_HELPER | ||
| 10 | select DRM_TTM | 6 | select DRM_TTM |
| 11 | help | 7 | help |
| 12 | Say yes for experimental AST GPU driver. Do not enable | 8 | Say yes for experimental AST GPU driver. Do not enable |
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 7bc3aa6dda8c..904beaa932d0 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c | |||
| @@ -295,9 +295,8 @@ static int ast_get_dram_info(struct drm_device *dev) | |||
| 295 | static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb) | 295 | static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb) |
| 296 | { | 296 | { |
| 297 | struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb); | 297 | struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb); |
| 298 | if (ast_fb->obj) | ||
| 299 | drm_gem_object_unreference_unlocked(ast_fb->obj); | ||
| 300 | 298 | ||
| 299 | drm_gem_object_unreference_unlocked(ast_fb->obj); | ||
| 301 | drm_framebuffer_cleanup(fb); | 300 | drm_framebuffer_cleanup(fb); |
| 302 | kfree(fb); | 301 | kfree(fb); |
| 303 | } | 302 | } |
diff --git a/drivers/gpu/drm/atmel-hlcdc/Kconfig b/drivers/gpu/drm/atmel-hlcdc/Kconfig index 99b4f0698a30..32bcc4bad06a 100644 --- a/drivers/gpu/drm/atmel-hlcdc/Kconfig +++ b/drivers/gpu/drm/atmel-hlcdc/Kconfig | |||
| @@ -3,7 +3,6 @@ config DRM_ATMEL_HLCDC | |||
| 3 | depends on DRM && OF && COMMON_CLK && MFD_ATMEL_HLCDC && ARM | 3 | depends on DRM && OF && COMMON_CLK && MFD_ATMEL_HLCDC && ARM |
| 4 | select DRM_GEM_CMA_HELPER | 4 | select DRM_GEM_CMA_HELPER |
| 5 | select DRM_KMS_HELPER | 5 | select DRM_KMS_HELPER |
| 6 | select DRM_KMS_FB_HELPER | ||
| 7 | select DRM_KMS_CMA_HELPER | 6 | select DRM_KMS_CMA_HELPER |
| 8 | select DRM_PANEL | 7 | select DRM_PANEL |
| 9 | help | 8 | help |
diff --git a/drivers/gpu/drm/bochs/Kconfig b/drivers/gpu/drm/bochs/Kconfig index 5f8b0c2b9a44..f739763f47ce 100644 --- a/drivers/gpu/drm/bochs/Kconfig +++ b/drivers/gpu/drm/bochs/Kconfig | |||
| @@ -2,10 +2,6 @@ config DRM_BOCHS | |||
| 2 | tristate "DRM Support for bochs dispi vga interface (qemu stdvga)" | 2 | tristate "DRM Support for bochs dispi vga interface (qemu stdvga)" |
| 3 | depends on DRM && PCI | 3 | depends on DRM && PCI |
| 4 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 5 | select DRM_KMS_FB_HELPER | ||
| 6 | select FB_SYS_FILLRECT | ||
| 7 | select FB_SYS_COPYAREA | ||
| 8 | select FB_SYS_IMAGEBLIT | ||
| 9 | select DRM_TTM | 5 | select DRM_TTM |
| 10 | help | 6 | help |
| 11 | Choose this option for qemu. | 7 | Choose this option for qemu. |
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c index b109fdcaa679..5c5638a777a1 100644 --- a/drivers/gpu/drm/bochs/bochs_mm.c +++ b/drivers/gpu/drm/bochs/bochs_mm.c | |||
| @@ -465,8 +465,8 @@ int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, | |||
| 465 | static void bochs_user_framebuffer_destroy(struct drm_framebuffer *fb) | 465 | static void bochs_user_framebuffer_destroy(struct drm_framebuffer *fb) |
| 466 | { | 466 | { |
| 467 | struct bochs_framebuffer *bochs_fb = to_bochs_framebuffer(fb); | 467 | struct bochs_framebuffer *bochs_fb = to_bochs_framebuffer(fb); |
| 468 | if (bochs_fb->obj) | 468 | |
| 469 | drm_gem_object_unreference_unlocked(bochs_fb->obj); | 469 | drm_gem_object_unreference_unlocked(bochs_fb->obj); |
| 470 | drm_framebuffer_cleanup(fb); | 470 | drm_framebuffer_cleanup(fb); |
| 471 | kfree(fb); | 471 | kfree(fb); |
| 472 | } | 472 | } |
diff --git a/drivers/gpu/drm/cirrus/Kconfig b/drivers/gpu/drm/cirrus/Kconfig index 9864559e5fb9..04b3c161dfae 100644 --- a/drivers/gpu/drm/cirrus/Kconfig +++ b/drivers/gpu/drm/cirrus/Kconfig | |||
| @@ -1,11 +1,7 @@ | |||
| 1 | config DRM_CIRRUS_QEMU | 1 | config DRM_CIRRUS_QEMU |
| 2 | tristate "Cirrus driver for QEMU emulated device" | 2 | tristate "Cirrus driver for QEMU emulated device" |
| 3 | depends on DRM && PCI | 3 | depends on DRM && PCI |
| 4 | select FB_SYS_FILLRECT | ||
| 5 | select FB_SYS_COPYAREA | ||
| 6 | select FB_SYS_IMAGEBLIT | ||
| 7 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 8 | select DRM_KMS_FB_HELPER | ||
| 9 | select DRM_TTM | 5 | select DRM_TTM |
| 10 | help | 6 | help |
| 11 | This is a KMS driver for emulated cirrus device in qemu. | 7 | This is a KMS driver for emulated cirrus device in qemu. |
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c index 32d32c5b7b17..80446e2d3ab6 100644 --- a/drivers/gpu/drm/cirrus/cirrus_main.c +++ b/drivers/gpu/drm/cirrus/cirrus_main.c | |||
| @@ -17,8 +17,8 @@ | |||
| 17 | static void cirrus_user_framebuffer_destroy(struct drm_framebuffer *fb) | 17 | static void cirrus_user_framebuffer_destroy(struct drm_framebuffer *fb) |
| 18 | { | 18 | { |
| 19 | struct cirrus_framebuffer *cirrus_fb = to_cirrus_framebuffer(fb); | 19 | struct cirrus_framebuffer *cirrus_fb = to_cirrus_framebuffer(fb); |
| 20 | if (cirrus_fb->obj) | 20 | |
| 21 | drm_gem_object_unreference_unlocked(cirrus_fb->obj); | 21 | drm_gem_object_unreference_unlocked(cirrus_fb->obj); |
| 22 | drm_framebuffer_cleanup(fb); | 22 | drm_framebuffer_cleanup(fb); |
| 23 | kfree(fb); | 23 | kfree(fb); |
| 24 | } | 24 | } |
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 9359be4a0ca9..8d2f111fa113 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
| @@ -404,8 +404,7 @@ drm_atomic_replace_property_blob(struct drm_property_blob **blob, | |||
| 404 | if (old_blob == new_blob) | 404 | if (old_blob == new_blob) |
| 405 | return; | 405 | return; |
| 406 | 406 | ||
| 407 | if (old_blob) | 407 | drm_property_unreference_blob(old_blob); |
| 408 | drm_property_unreference_blob(old_blob); | ||
| 409 | if (new_blob) | 408 | if (new_blob) |
| 410 | drm_property_reference_blob(new_blob); | 409 | drm_property_reference_blob(new_blob); |
| 411 | *blob = new_blob; | 410 | *blob = new_blob; |
| @@ -1589,72 +1588,6 @@ void drm_atomic_clean_old_fb(struct drm_device *dev, | |||
| 1589 | } | 1588 | } |
| 1590 | EXPORT_SYMBOL(drm_atomic_clean_old_fb); | 1589 | EXPORT_SYMBOL(drm_atomic_clean_old_fb); |
| 1591 | 1590 | ||
| 1592 | int drm_atomic_remove_fb(struct drm_framebuffer *fb) | ||
| 1593 | { | ||
| 1594 | struct drm_modeset_acquire_ctx ctx; | ||
| 1595 | struct drm_device *dev = fb->dev; | ||
| 1596 | struct drm_atomic_state *state; | ||
| 1597 | struct drm_plane *plane; | ||
| 1598 | int ret = 0; | ||
| 1599 | unsigned plane_mask; | ||
| 1600 | |||
| 1601 | state = drm_atomic_state_alloc(dev); | ||
| 1602 | if (!state) | ||
| 1603 | return -ENOMEM; | ||
| 1604 | |||
| 1605 | drm_modeset_acquire_init(&ctx, 0); | ||
| 1606 | state->acquire_ctx = &ctx; | ||
| 1607 | |||
| 1608 | retry: | ||
| 1609 | plane_mask = 0; | ||
| 1610 | ret = drm_modeset_lock_all_ctx(dev, &ctx); | ||
| 1611 | if (ret) | ||
| 1612 | goto unlock; | ||
| 1613 | |||
| 1614 | drm_for_each_plane(plane, dev) { | ||
| 1615 | struct drm_plane_state *plane_state; | ||
| 1616 | |||
| 1617 | if (plane->state->fb != fb) | ||
| 1618 | continue; | ||
| 1619 | |||
| 1620 | plane_state = drm_atomic_get_plane_state(state, plane); | ||
| 1621 | if (IS_ERR(plane_state)) { | ||
| 1622 | ret = PTR_ERR(plane_state); | ||
| 1623 | goto unlock; | ||
| 1624 | } | ||
| 1625 | |||
| 1626 | drm_atomic_set_fb_for_plane(plane_state, NULL); | ||
| 1627 | ret = drm_atomic_set_crtc_for_plane(plane_state, NULL); | ||
| 1628 | if (ret) | ||
| 1629 | goto unlock; | ||
| 1630 | |||
| 1631 | plane_mask |= BIT(drm_plane_index(plane)); | ||
| 1632 | |||
| 1633 | plane->old_fb = plane->fb; | ||
| 1634 | plane->fb = NULL; | ||
| 1635 | } | ||
| 1636 | |||
| 1637 | if (plane_mask) | ||
| 1638 | ret = drm_atomic_commit(state); | ||
| 1639 | |||
| 1640 | unlock: | ||
| 1641 | if (plane_mask) | ||
| 1642 | drm_atomic_clean_old_fb(dev, plane_mask, ret); | ||
| 1643 | |||
| 1644 | if (ret == -EDEADLK) { | ||
| 1645 | drm_modeset_backoff(&ctx); | ||
| 1646 | goto retry; | ||
| 1647 | } | ||
| 1648 | |||
| 1649 | if (ret || !plane_mask) | ||
| 1650 | drm_atomic_state_free(state); | ||
| 1651 | |||
| 1652 | drm_modeset_drop_locks(&ctx); | ||
| 1653 | drm_modeset_acquire_fini(&ctx); | ||
| 1654 | |||
| 1655 | return ret; | ||
| 1656 | } | ||
| 1657 | |||
| 1658 | int drm_mode_atomic_ioctl(struct drm_device *dev, | 1591 | int drm_mode_atomic_ioctl(struct drm_device *dev, |
| 1659 | void *data, struct drm_file *file_priv) | 1592 | void *data, struct drm_file *file_priv) |
| 1660 | { | 1593 | { |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 9d3f80efc9cc..f1d9f0569d7f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -613,11 +613,6 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) | |||
| 613 | * in this manner. | 613 | * in this manner. |
| 614 | */ | 614 | */ |
| 615 | if (drm_framebuffer_read_refcount(fb) > 1) { | 615 | if (drm_framebuffer_read_refcount(fb) > 1) { |
| 616 | if (dev->mode_config.funcs->atomic_commit) { | ||
| 617 | drm_atomic_remove_fb(fb); | ||
| 618 | goto out; | ||
| 619 | } | ||
| 620 | |||
| 621 | drm_modeset_lock_all(dev); | 616 | drm_modeset_lock_all(dev); |
| 622 | /* remove from any CRTC */ | 617 | /* remove from any CRTC */ |
| 623 | drm_for_each_crtc(crtc, dev) { | 618 | drm_for_each_crtc(crtc, dev) { |
| @@ -635,7 +630,6 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) | |||
| 635 | drm_modeset_unlock_all(dev); | 630 | drm_modeset_unlock_all(dev); |
| 636 | } | 631 | } |
| 637 | 632 | ||
| 638 | out: | ||
| 639 | drm_framebuffer_unreference(fb); | 633 | drm_framebuffer_unreference(fb); |
| 640 | } | 634 | } |
| 641 | EXPORT_SYMBOL(drm_framebuffer_remove); | 635 | EXPORT_SYMBOL(drm_framebuffer_remove); |
| @@ -934,11 +928,11 @@ int drm_connector_init(struct drm_device *dev, | |||
| 934 | connector->dev = dev; | 928 | connector->dev = dev; |
| 935 | connector->funcs = funcs; | 929 | connector->funcs = funcs; |
| 936 | 930 | ||
| 937 | connector->connector_id = ida_simple_get(&config->connector_ida, 0, 0, GFP_KERNEL); | 931 | ret = ida_simple_get(&config->connector_ida, 0, 0, GFP_KERNEL); |
| 938 | if (connector->connector_id < 0) { | 932 | if (ret < 0) |
| 939 | ret = connector->connector_id; | ||
| 940 | goto out_put; | 933 | goto out_put; |
| 941 | } | 934 | connector->index = ret; |
| 935 | ret = 0; | ||
| 942 | 936 | ||
| 943 | connector->connector_type = connector_type; | 937 | connector->connector_type = connector_type; |
| 944 | connector->connector_type_id = | 938 | connector->connector_type_id = |
| @@ -986,7 +980,7 @@ out_put_type_id: | |||
| 986 | ida_remove(connector_ida, connector->connector_type_id); | 980 | ida_remove(connector_ida, connector->connector_type_id); |
| 987 | out_put_id: | 981 | out_put_id: |
| 988 | if (ret) | 982 | if (ret) |
| 989 | ida_remove(&config->connector_ida, connector->connector_id); | 983 | ida_remove(&config->connector_ida, connector->index); |
| 990 | out_put: | 984 | out_put: |
| 991 | if (ret) | 985 | if (ret) |
| 992 | drm_mode_object_unregister(dev, &connector->base); | 986 | drm_mode_object_unregister(dev, &connector->base); |
| @@ -1030,7 +1024,7 @@ void drm_connector_cleanup(struct drm_connector *connector) | |||
| 1030 | connector->connector_type_id); | 1024 | connector->connector_type_id); |
| 1031 | 1025 | ||
| 1032 | ida_remove(&dev->mode_config.connector_ida, | 1026 | ida_remove(&dev->mode_config.connector_ida, |
| 1033 | connector->connector_id); | 1027 | connector->index); |
| 1034 | 1028 | ||
| 1035 | kfree(connector->display_info.bus_formats); | 1029 | kfree(connector->display_info.bus_formats); |
| 1036 | drm_mode_object_unregister(dev, &connector->base); | 1030 | drm_mode_object_unregister(dev, &connector->base); |
| @@ -1113,6 +1107,15 @@ void drm_connector_unregister(struct drm_connector *connector) | |||
| 1113 | } | 1107 | } |
| 1114 | EXPORT_SYMBOL(drm_connector_unregister); | 1108 | EXPORT_SYMBOL(drm_connector_unregister); |
| 1115 | 1109 | ||
| 1110 | static void drm_connector_unregister_all(struct drm_device *dev) | ||
| 1111 | { | ||
| 1112 | struct drm_connector *connector; | ||
| 1113 | |||
| 1114 | /* FIXME: taking the mode config mutex ends up in a clash with sysfs */ | ||
| 1115 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
| 1116 | drm_connector_unregister(connector); | ||
| 1117 | } | ||
| 1118 | |||
| 1116 | static int drm_connector_register_all(struct drm_device *dev) | 1119 | static int drm_connector_register_all(struct drm_device *dev) |
| 1117 | { | 1120 | { |
| 1118 | struct drm_connector *connector; | 1121 | struct drm_connector *connector; |
| @@ -1136,26 +1139,6 @@ err: | |||
| 1136 | return ret; | 1139 | return ret; |
| 1137 | } | 1140 | } |
| 1138 | 1141 | ||
| 1139 | /** | ||
| 1140 | * drm_connector_unregister_all - unregister connector userspace interfaces | ||
| 1141 | * @dev: drm device | ||
| 1142 | * | ||
| 1143 | * This functions unregisters all connectors from sysfs and other places so | ||
| 1144 | * that userspace can no longer access them. Drivers should call this as the | ||
| 1145 | * first step tearing down the device instace, or when the underlying | ||
| 1146 | * physical device disappeared (e.g. USB unplug), right before calling | ||
| 1147 | * drm_dev_unregister(). | ||
| 1148 | */ | ||
| 1149 | void drm_connector_unregister_all(struct drm_device *dev) | ||
| 1150 | { | ||
| 1151 | struct drm_connector *connector; | ||
| 1152 | |||
| 1153 | /* FIXME: taking the mode config mutex ends up in a clash with sysfs */ | ||
| 1154 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
| 1155 | drm_connector_unregister(connector); | ||
| 1156 | } | ||
| 1157 | EXPORT_SYMBOL(drm_connector_unregister_all); | ||
| 1158 | |||
| 1159 | static int drm_encoder_register_all(struct drm_device *dev) | 1142 | static int drm_encoder_register_all(struct drm_device *dev) |
| 1160 | { | 1143 | { |
| 1161 | struct drm_encoder *encoder; | 1144 | struct drm_encoder *encoder; |
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index b248e2238a05..47a500b90fd7 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h | |||
| @@ -125,7 +125,6 @@ int drm_atomic_get_property(struct drm_mode_object *obj, | |||
| 125 | struct drm_property *property, uint64_t *val); | 125 | struct drm_property *property, uint64_t *val); |
| 126 | int drm_mode_atomic_ioctl(struct drm_device *dev, | 126 | int drm_mode_atomic_ioctl(struct drm_device *dev, |
| 127 | void *data, struct drm_file *file_priv); | 127 | void *data, struct drm_file *file_priv); |
| 128 | int drm_atomic_remove_fb(struct drm_framebuffer *fb); | ||
| 129 | 128 | ||
| 130 | int drm_modeset_register_all(struct drm_device *dev); | 129 | int drm_modeset_register_all(struct drm_device *dev); |
| 131 | void drm_modeset_unregister_all(struct drm_device *dev); | 130 | void drm_modeset_unregister_all(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 6537908050d7..04e457117980 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
| @@ -1493,11 +1493,8 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) | |||
| 1493 | WARN_ON(!mutex_is_locked(&mgr->qlock)); | 1493 | WARN_ON(!mutex_is_locked(&mgr->qlock)); |
| 1494 | 1494 | ||
| 1495 | /* construct a chunk from the first msg in the tx_msg queue */ | 1495 | /* construct a chunk from the first msg in the tx_msg queue */ |
| 1496 | if (list_empty(&mgr->tx_msg_downq)) { | 1496 | if (list_empty(&mgr->tx_msg_downq)) |
| 1497 | mgr->tx_down_in_progress = false; | ||
| 1498 | return; | 1497 | return; |
| 1499 | } | ||
| 1500 | mgr->tx_down_in_progress = true; | ||
| 1501 | 1498 | ||
| 1502 | txmsg = list_first_entry(&mgr->tx_msg_downq, struct drm_dp_sideband_msg_tx, next); | 1499 | txmsg = list_first_entry(&mgr->tx_msg_downq, struct drm_dp_sideband_msg_tx, next); |
| 1503 | ret = process_single_tx_qlock(mgr, txmsg, false); | 1500 | ret = process_single_tx_qlock(mgr, txmsg, false); |
| @@ -1512,10 +1509,6 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) | |||
| 1512 | txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT; | 1509 | txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT; |
| 1513 | wake_up(&mgr->tx_waitq); | 1510 | wake_up(&mgr->tx_waitq); |
| 1514 | } | 1511 | } |
| 1515 | if (list_empty(&mgr->tx_msg_downq)) { | ||
| 1516 | mgr->tx_down_in_progress = false; | ||
| 1517 | return; | ||
| 1518 | } | ||
| 1519 | } | 1512 | } |
| 1520 | 1513 | ||
| 1521 | /* called holding qlock */ | 1514 | /* called holding qlock */ |
| @@ -1538,7 +1531,7 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr, | |||
| 1538 | { | 1531 | { |
| 1539 | mutex_lock(&mgr->qlock); | 1532 | mutex_lock(&mgr->qlock); |
| 1540 | list_add_tail(&txmsg->next, &mgr->tx_msg_downq); | 1533 | list_add_tail(&txmsg->next, &mgr->tx_msg_downq); |
| 1541 | if (!mgr->tx_down_in_progress) | 1534 | if (list_is_singular(&mgr->tx_msg_downq)) |
| 1542 | process_single_down_tx_qlock(mgr); | 1535 | process_single_down_tx_qlock(mgr); |
| 1543 | mutex_unlock(&mgr->qlock); | 1536 | mutex_unlock(&mgr->qlock); |
| 1544 | } | 1537 | } |
| @@ -2372,6 +2365,7 @@ EXPORT_SYMBOL(drm_dp_mst_hpd_irq); | |||
| 2372 | 2365 | ||
| 2373 | /** | 2366 | /** |
| 2374 | * drm_dp_mst_detect_port() - get connection status for an MST port | 2367 | * drm_dp_mst_detect_port() - get connection status for an MST port |
| 2368 | * @connector: DRM connector for this port | ||
| 2375 | * @mgr: manager for this port | 2369 | * @mgr: manager for this port |
| 2376 | * @port: unverified pointer to a port | 2370 | * @port: unverified pointer to a port |
| 2377 | * | 2371 | * |
| @@ -2887,7 +2881,7 @@ static void drm_dp_tx_work(struct work_struct *work) | |||
| 2887 | struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work); | 2881 | struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work); |
| 2888 | 2882 | ||
| 2889 | mutex_lock(&mgr->qlock); | 2883 | mutex_lock(&mgr->qlock); |
| 2890 | if (mgr->tx_down_in_progress) | 2884 | if (!list_empty(&mgr->tx_msg_downq)) |
| 2891 | process_single_down_tx_qlock(mgr); | 2885 | process_single_down_tx_qlock(mgr); |
| 2892 | mutex_unlock(&mgr->qlock); | 2886 | mutex_unlock(&mgr->qlock); |
| 2893 | } | 2887 | } |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 35c86acede38..77f357b2c386 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -1695,7 +1695,6 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
| 1695 | 1695 | ||
| 1696 | DRM_DEBUG("waiting on vblank count %d, crtc %u\n", | 1696 | DRM_DEBUG("waiting on vblank count %d, crtc %u\n", |
| 1697 | vblwait->request.sequence, pipe); | 1697 | vblwait->request.sequence, pipe); |
| 1698 | vblank->last_wait = vblwait->request.sequence; | ||
| 1699 | DRM_WAIT_ON(ret, vblank->queue, 3 * HZ, | 1698 | DRM_WAIT_ON(ret, vblank->queue, 3 * HZ, |
| 1700 | (((drm_vblank_count(dev, pipe) - | 1699 | (((drm_vblank_count(dev, pipe) - |
| 1701 | vblwait->request.sequence) <= (1 << 23)) || | 1700 | vblwait->request.sequence) <= (1 << 23)) || |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 67dcd6831291..fb49443bfd32 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
| @@ -269,8 +269,7 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev, | |||
| 269 | struct exynos_drm_gem *exynos_gem = exynos_fbd->exynos_gem; | 269 | struct exynos_drm_gem *exynos_gem = exynos_fbd->exynos_gem; |
| 270 | struct drm_framebuffer *fb; | 270 | struct drm_framebuffer *fb; |
| 271 | 271 | ||
| 272 | if (exynos_gem->kvaddr) | 272 | vunmap(exynos_gem->kvaddr); |
| 273 | vunmap(exynos_gem->kvaddr); | ||
| 274 | 273 | ||
| 275 | /* release drm framebuffer and real buffer */ | 274 | /* release drm framebuffer and real buffer */ |
| 276 | if (fb_helper->fb && fb_helper->fb->funcs) { | 275 | if (fb_helper->fb && fb_helper->fb->funcs) { |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 1625d7c8a319..2275efe41acd 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -1820,6 +1820,7 @@ static int hdmi_probe(struct platform_device *pdev) | |||
| 1820 | DRM_ERROR("Failed to find ddc node in device tree\n"); | 1820 | DRM_ERROR("Failed to find ddc node in device tree\n"); |
| 1821 | return -ENODEV; | 1821 | return -ENODEV; |
| 1822 | } | 1822 | } |
| 1823 | of_node_put(dev->of_node); | ||
| 1823 | 1824 | ||
| 1824 | out_get_ddc_adpt: | 1825 | out_get_ddc_adpt: |
| 1825 | hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node); | 1826 | hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node); |
| @@ -1838,6 +1839,7 @@ out_get_ddc_adpt: | |||
| 1838 | ret = -ENODEV; | 1839 | ret = -ENODEV; |
| 1839 | goto err_ddc; | 1840 | goto err_ddc; |
| 1840 | } | 1841 | } |
| 1842 | of_node_put(dev->of_node); | ||
| 1841 | 1843 | ||
| 1842 | out_get_phy_port: | 1844 | out_get_phy_port: |
| 1843 | if (hdata->drv_data->is_apb_phy) { | 1845 | if (hdata->drv_data->is_apb_phy) { |
diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig b/drivers/gpu/drm/fsl-dcu/Kconfig index b9c714de6e40..14a72c4c496d 100644 --- a/drivers/gpu/drm/fsl-dcu/Kconfig +++ b/drivers/gpu/drm/fsl-dcu/Kconfig | |||
| @@ -5,12 +5,7 @@ config DRM_FSL_DCU | |||
| 5 | select BACKLIGHT_LCD_SUPPORT | 5 | select BACKLIGHT_LCD_SUPPORT |
| 6 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
| 7 | select DRM_KMS_CMA_HELPER | 7 | select DRM_KMS_CMA_HELPER |
| 8 | select DRM_KMS_FB_HELPER | ||
| 9 | select DRM_PANEL | 8 | select DRM_PANEL |
| 10 | select FB_SYS_FILLRECT | ||
| 11 | select FB_SYS_COPYAREA | ||
| 12 | select FB_SYS_IMAGEBLIT | ||
| 13 | select FB_SYS_FOPS | ||
| 14 | select REGMAP_MMIO | 9 | select REGMAP_MMIO |
| 15 | select VIDEOMODE_HELPERS | 10 | select VIDEOMODE_HELPERS |
| 16 | help | 11 | help |
diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig index 17f928ec84ea..8906d67494fc 100644 --- a/drivers/gpu/drm/gma500/Kconfig +++ b/drivers/gpu/drm/gma500/Kconfig | |||
| @@ -1,11 +1,7 @@ | |||
| 1 | config DRM_GMA500 | 1 | config DRM_GMA500 |
| 2 | tristate "Intel GMA5/600 KMS Framebuffer" | 2 | tristate "Intel GMA5/600 KMS Framebuffer" |
| 3 | depends on DRM && PCI && X86 | 3 | depends on DRM && PCI && X86 |
| 4 | select FB_CFB_COPYAREA | ||
| 5 | select FB_CFB_FILLRECT | ||
| 6 | select FB_CFB_IMAGEBLIT | ||
| 7 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 8 | select DRM_KMS_FB_HELPER | ||
| 9 | select DRM_TTM | 5 | select DRM_TTM |
| 10 | # GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915 | 6 | # GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915 |
| 11 | select ACPI_VIDEO if ACPI | 7 | select ACPI_VIDEO if ACPI |
diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig index a1844b50546c..f2c9ae822149 100644 --- a/drivers/gpu/drm/imx/Kconfig +++ b/drivers/gpu/drm/imx/Kconfig | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | config DRM_IMX | 1 | config DRM_IMX |
| 2 | tristate "DRM Support for Freescale i.MX" | 2 | tristate "DRM Support for Freescale i.MX" |
| 3 | select DRM_KMS_HELPER | 3 | select DRM_KMS_HELPER |
| 4 | select DRM_KMS_FB_HELPER | ||
| 5 | select VIDEOMODE_HELPERS | 4 | select VIDEOMODE_HELPERS |
| 6 | select DRM_GEM_CMA_HELPER | 5 | select DRM_GEM_CMA_HELPER |
| 7 | select DRM_KMS_CMA_HELPER | 6 | select DRM_KMS_CMA_HELPER |
diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index 3a1c5fbae54a..520e5e668d6c 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig | |||
| @@ -1,11 +1,7 @@ | |||
| 1 | config DRM_MGAG200 | 1 | config DRM_MGAG200 |
| 2 | tristate "Kernel modesetting driver for MGA G200 server engines" | 2 | tristate "Kernel modesetting driver for MGA G200 server engines" |
| 3 | depends on DRM && PCI | 3 | depends on DRM && PCI |
| 4 | select FB_SYS_FILLRECT | ||
| 5 | select FB_SYS_COPYAREA | ||
| 6 | select FB_SYS_IMAGEBLIT | ||
| 7 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 8 | select DRM_KMS_FB_HELPER | ||
| 9 | select DRM_TTM | 5 | select DRM_TTM |
| 10 | help | 6 | help |
| 11 | This is a KMS driver for the MGA G200 server chips, it | 7 | This is a KMS driver for the MGA G200 server chips, it |
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 5ab13e7939db..2922a82cba8e 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig | |||
| @@ -3,13 +3,7 @@ config DRM_NOUVEAU | |||
| 3 | depends on DRM && PCI | 3 | depends on DRM && PCI |
| 4 | select FW_LOADER | 4 | select FW_LOADER |
| 5 | select DRM_KMS_HELPER | 5 | select DRM_KMS_HELPER |
| 6 | select DRM_KMS_FB_HELPER | ||
| 7 | select DRM_TTM | 6 | select DRM_TTM |
| 8 | select FB_CFB_FILLRECT | ||
| 9 | select FB_CFB_COPYAREA | ||
| 10 | select FB_CFB_IMAGEBLIT | ||
| 11 | select FB | ||
| 12 | select FRAMEBUFFER_CONSOLE if !EXPERT | ||
| 13 | select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT | 7 | select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT |
| 14 | select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && INPUT | 8 | select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && INPUT |
| 15 | select X86_PLATFORM_DEVICES if ACPI && X86 | 9 | select X86_PLATFORM_DEVICES if ACPI && X86 |
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig index 336ad4de9981..556f81f6b2c7 100644 --- a/drivers/gpu/drm/omapdrm/Kconfig +++ b/drivers/gpu/drm/omapdrm/Kconfig | |||
| @@ -4,11 +4,6 @@ config DRM_OMAP | |||
| 4 | depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM | 4 | depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM |
| 5 | select OMAP2_DSS | 5 | select OMAP2_DSS |
| 6 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
| 7 | select DRM_KMS_FB_HELPER | ||
| 8 | select FB_SYS_FILLRECT | ||
| 9 | select FB_SYS_COPYAREA | ||
| 10 | select FB_SYS_IMAGEBLIT | ||
| 11 | select FB_SYS_FOPS | ||
| 12 | default n | 7 | default n |
| 13 | help | 8 | help |
| 14 | DRM display driver for OMAP2/3/4 based boards. | 9 | DRM display driver for OMAP2/3/4 based boards. |
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index 75f7827525cf..684b7aeda411 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c | |||
| @@ -255,6 +255,7 @@ static int dvic_probe_of(struct platform_device *pdev) | |||
| 255 | adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0); | 255 | adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0); |
| 256 | if (adapter_node) { | 256 | if (adapter_node) { |
| 257 | adapter = of_get_i2c_adapter_by_node(adapter_node); | 257 | adapter = of_get_i2c_adapter_by_node(adapter_node); |
| 258 | of_node_put(adapter_node); | ||
| 258 | if (adapter == NULL) { | 259 | if (adapter == NULL) { |
| 259 | dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n"); | 260 | dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n"); |
| 260 | omap_dss_put_device(ddata->in); | 261 | omap_dss_put_device(ddata->in); |
diff --git a/drivers/gpu/drm/omapdrm/dss/dss-of.c b/drivers/gpu/drm/omapdrm/dss/dss-of.c index dfd4e9621e3b..e256d879b25c 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss-of.c +++ b/drivers/gpu/drm/omapdrm/dss/dss-of.c | |||
| @@ -125,15 +125,16 @@ u32 dss_of_port_get_port_number(struct device_node *port) | |||
| 125 | 125 | ||
| 126 | static struct device_node *omapdss_of_get_remote_port(const struct device_node *node) | 126 | static struct device_node *omapdss_of_get_remote_port(const struct device_node *node) |
| 127 | { | 127 | { |
| 128 | struct device_node *np; | 128 | struct device_node *np, *np_parent; |
| 129 | 129 | ||
| 130 | np = of_parse_phandle(node, "remote-endpoint", 0); | 130 | np = of_parse_phandle(node, "remote-endpoint", 0); |
| 131 | if (!np) | 131 | if (!np) |
| 132 | return NULL; | 132 | return NULL; |
| 133 | 133 | ||
| 134 | np = of_get_next_parent(np); | 134 | np_parent = of_get_next_parent(np); |
| 135 | of_node_put(np); | ||
| 135 | 136 | ||
| 136 | return np; | 137 | return np_parent; |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | struct device_node * | 140 | struct device_node * |
diff --git a/drivers/gpu/drm/qxl/Kconfig b/drivers/gpu/drm/qxl/Kconfig index 38c2bb72e456..da45b11b66b8 100644 --- a/drivers/gpu/drm/qxl/Kconfig +++ b/drivers/gpu/drm/qxl/Kconfig | |||
| @@ -1,12 +1,7 @@ | |||
| 1 | config DRM_QXL | 1 | config DRM_QXL |
| 2 | tristate "QXL virtual GPU" | 2 | tristate "QXL virtual GPU" |
| 3 | depends on DRM && PCI | 3 | depends on DRM && PCI |
| 4 | select FB_SYS_FILLRECT | ||
| 5 | select FB_SYS_COPYAREA | ||
| 6 | select FB_SYS_IMAGEBLIT | ||
| 7 | select FB_DEFERRED_IO | ||
| 8 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 9 | select DRM_KMS_FB_HELPER | ||
| 10 | select DRM_TTM | 5 | select DRM_TTM |
| 11 | select CRC32 | 6 | select CRC32 |
| 12 | help | 7 | help |
diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig index 7fc3ca5ce6c7..4c2fd056dd6d 100644 --- a/drivers/gpu/drm/rcar-du/Kconfig +++ b/drivers/gpu/drm/rcar-du/Kconfig | |||
| @@ -6,7 +6,6 @@ config DRM_RCAR_DU | |||
| 6 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
| 7 | select DRM_KMS_CMA_HELPER | 7 | select DRM_KMS_CMA_HELPER |
| 8 | select DRM_GEM_CMA_HELPER | 8 | select DRM_GEM_CMA_HELPER |
| 9 | select DRM_KMS_FB_HELPER | ||
| 10 | select VIDEOMODE_HELPERS | 9 | select VIDEOMODE_HELPERS |
| 11 | help | 10 | help |
| 12 | Choose this option if you have an R-Car chipset. | 11 | Choose this option if you have an R-Car chipset. |
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index e48611e83c03..3c58669a06ce 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig | |||
| @@ -4,11 +4,7 @@ config DRM_ROCKCHIP | |||
| 4 | depends on RESET_CONTROLLER | 4 | depends on RESET_CONTROLLER |
| 5 | select DRM_GEM_CMA_HELPER | 5 | select DRM_GEM_CMA_HELPER |
| 6 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
| 7 | select DRM_KMS_FB_HELPER | ||
| 8 | select DRM_PANEL | 7 | select DRM_PANEL |
| 9 | select FB_CFB_FILLRECT | ||
| 10 | select FB_CFB_COPYAREA | ||
| 11 | select FB_CFB_IMAGEBLIT | ||
| 12 | select VIDEOMODE_HELPERS | 8 | select VIDEOMODE_HELPERS |
| 13 | help | 9 | help |
| 14 | Choose this option if you have a Rockchip soc chipset. | 10 | Choose this option if you have a Rockchip soc chipset. |
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index e81e19a660ad..89aadbf465f8 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | |||
| @@ -96,6 +96,7 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data) | |||
| 96 | ret = rockchip_dp_pre_init(dp); | 96 | ret = rockchip_dp_pre_init(dp); |
| 97 | if (ret < 0) { | 97 | if (ret < 0) { |
| 98 | dev_err(dp->dev, "failed to dp pre init %d\n", ret); | 98 | dev_err(dp->dev, "failed to dp pre init %d\n", ret); |
| 99 | clk_disable_unprepare(dp->pclk); | ||
| 99 | return ret; | 100 | return ret; |
| 100 | } | 101 | } |
| 101 | 102 | ||
| @@ -272,6 +273,7 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp) | |||
| 272 | ret = rockchip_dp_pre_init(dp); | 273 | ret = rockchip_dp_pre_init(dp); |
| 273 | if (ret < 0) { | 274 | if (ret < 0) { |
| 274 | dev_err(dp->dev, "failed to pre init %d\n", ret); | 275 | dev_err(dp->dev, "failed to pre init %d\n", ret); |
| 276 | clk_disable_unprepare(dp->pclk); | ||
| 275 | return ret; | 277 | return ret; |
| 276 | } | 278 | } |
| 277 | 279 | ||
diff --git a/drivers/gpu/drm/shmobile/Kconfig b/drivers/gpu/drm/shmobile/Kconfig index 8d17d00ddb4b..c987c826daa3 100644 --- a/drivers/gpu/drm/shmobile/Kconfig +++ b/drivers/gpu/drm/shmobile/Kconfig | |||
| @@ -6,7 +6,6 @@ config DRM_SHMOBILE | |||
| 6 | select BACKLIGHT_CLASS_DEVICE | 6 | select BACKLIGHT_CLASS_DEVICE |
| 7 | select BACKLIGHT_LCD_SUPPORT | 7 | select BACKLIGHT_LCD_SUPPORT |
| 8 | select DRM_KMS_HELPER | 8 | select DRM_KMS_HELPER |
| 9 | select DRM_KMS_FB_HELPER | ||
| 10 | select DRM_KMS_CMA_HELPER | 9 | select DRM_KMS_CMA_HELPER |
| 11 | select DRM_GEM_CMA_HELPER | 10 | select DRM_GEM_CMA_HELPER |
| 12 | help | 11 | help |
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 4dc543e1db10..7092daaf6c43 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c | |||
| @@ -185,7 +185,6 @@ static void sun4i_drv_unbind(struct device *dev) | |||
| 185 | { | 185 | { |
| 186 | struct drm_device *drm = dev_get_drvdata(dev); | 186 | struct drm_device *drm = dev_get_drvdata(dev); |
| 187 | 187 | ||
| 188 | drm_connector_unregister_all(drm); | ||
| 189 | drm_dev_unregister(drm); | 188 | drm_dev_unregister(drm); |
| 190 | drm_kms_helper_poll_fini(drm); | 189 | drm_kms_helper_poll_fini(drm); |
| 191 | sun4i_framebuffer_free(drm); | 190 | sun4i_framebuffer_free(drm); |
diff --git a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c index a0b30c216a5b..70688febd7ac 100644 --- a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c +++ b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c | |||
| @@ -20,8 +20,7 @@ static void sun4i_de_output_poll_changed(struct drm_device *drm) | |||
| 20 | { | 20 | { |
| 21 | struct sun4i_drv *drv = drm->dev_private; | 21 | struct sun4i_drv *drv = drm->dev_private; |
| 22 | 22 | ||
| 23 | if (drv->fbdev) | 23 | drm_fbdev_cma_hotplug_event(drv->fbdev); |
| 24 | drm_fbdev_cma_hotplug_event(drv->fbdev); | ||
| 25 | } | 24 | } |
| 26 | 25 | ||
| 27 | static const struct drm_mode_config_funcs sun4i_de_mode_config_funcs = { | 26 | static const struct drm_mode_config_funcs sun4i_de_mode_config_funcs = { |
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 1b12aa7a715e..e6d71fa4028e 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c | |||
| @@ -68,7 +68,7 @@ static void tegra_fb_destroy(struct drm_framebuffer *framebuffer) | |||
| 68 | struct tegra_bo *bo = fb->planes[i]; | 68 | struct tegra_bo *bo = fb->planes[i]; |
| 69 | 69 | ||
| 70 | if (bo) { | 70 | if (bo) { |
| 71 | if (bo->pages && bo->vaddr) | 71 | if (bo->pages) |
| 72 | vunmap(bo->vaddr); | 72 | vunmap(bo->vaddr); |
| 73 | 73 | ||
| 74 | drm_gem_object_unreference_unlocked(&bo->gem); | 74 | drm_gem_object_unreference_unlocked(&bo->gem); |
diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig index f60a1ec84fa4..28fed7e206d0 100644 --- a/drivers/gpu/drm/tilcdc/Kconfig +++ b/drivers/gpu/drm/tilcdc/Kconfig | |||
| @@ -2,7 +2,6 @@ config DRM_TILCDC | |||
| 2 | tristate "DRM Support for TI LCDC Display Controller" | 2 | tristate "DRM Support for TI LCDC Display Controller" |
| 3 | depends on DRM && OF && ARM | 3 | depends on DRM && OF && ARM |
| 4 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 5 | select DRM_KMS_FB_HELPER | ||
| 6 | select DRM_KMS_CMA_HELPER | 5 | select DRM_KMS_CMA_HELPER |
| 7 | select DRM_GEM_CMA_HELPER | 6 | select DRM_GEM_CMA_HELPER |
| 8 | select VIDEOMODE_HELPERS | 7 | select VIDEOMODE_HELPERS |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 3452748dc43c..4054d804fe06 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
| @@ -146,7 +146,6 @@ static void ttm_bo_release_list(struct kref *list_kref) | |||
| 146 | BUG_ON(bo->mem.mm_node != NULL); | 146 | BUG_ON(bo->mem.mm_node != NULL); |
| 147 | BUG_ON(!list_empty(&bo->lru)); | 147 | BUG_ON(!list_empty(&bo->lru)); |
| 148 | BUG_ON(!list_empty(&bo->ddestroy)); | 148 | BUG_ON(!list_empty(&bo->ddestroy)); |
| 149 | |||
| 150 | ttm_tt_destroy(bo->ttm); | 149 | ttm_tt_destroy(bo->ttm); |
| 151 | atomic_dec(&bo->glob->bo_count); | 150 | atomic_dec(&bo->glob->bo_count); |
| 152 | fence_put(bo->moving); | 151 | fence_put(bo->moving); |
diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig index 613ab0622d6e..1616ec4f4d84 100644 --- a/drivers/gpu/drm/udl/Kconfig +++ b/drivers/gpu/drm/udl/Kconfig | |||
| @@ -4,12 +4,7 @@ config DRM_UDL | |||
| 4 | depends on USB_SUPPORT | 4 | depends on USB_SUPPORT |
| 5 | depends on USB_ARCH_HAS_HCD | 5 | depends on USB_ARCH_HAS_HCD |
| 6 | select USB | 6 | select USB |
| 7 | select FB_SYS_FILLRECT | ||
| 8 | select FB_SYS_COPYAREA | ||
| 9 | select FB_SYS_IMAGEBLIT | ||
| 10 | select FB_DEFERRED_IO | ||
| 11 | select DRM_KMS_HELPER | 7 | select DRM_KMS_HELPER |
| 12 | select DRM_KMS_FB_HELPER | ||
| 13 | help | 8 | help |
| 14 | This is a KMS driver for the USB displaylink video adapters. | 9 | This is a KMS driver for the USB displaylink video adapters. |
| 15 | Say M/Y to add support for these devices via drm/kms interfaces. | 10 | Say M/Y to add support for these devices via drm/kms interfaces. |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 25ed00872dbe..8b42d31a7f0e 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c | |||
| @@ -91,8 +91,7 @@ static void vc4_lastclose(struct drm_device *dev) | |||
| 91 | { | 91 | { |
| 92 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 92 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 93 | 93 | ||
| 94 | if (vc4->fbdev) | 94 | drm_fbdev_cma_restore_mode(vc4->fbdev); |
| 95 | drm_fbdev_cma_restore_mode(vc4->fbdev); | ||
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | static const struct file_operations vc4_drm_fops = { | 97 | static const struct file_operations vc4_drm_fops = { |
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 9a217fd025f3..4ac894d993cd 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c | |||
| @@ -26,8 +26,7 @@ static void vc4_output_poll_changed(struct drm_device *dev) | |||
| 26 | { | 26 | { |
| 27 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 27 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 28 | 28 | ||
| 29 | if (vc4->fbdev) | 29 | drm_fbdev_cma_hotplug_event(vc4->fbdev); |
| 30 | drm_fbdev_cma_hotplug_event(vc4->fbdev); | ||
| 31 | } | 30 | } |
| 32 | 31 | ||
| 33 | struct vc4_commit { | 32 | struct vc4_commit { |
diff --git a/drivers/gpu/drm/vgem/Makefile b/drivers/gpu/drm/vgem/Makefile index 3f4c7b842028..bfcdea1330e6 100644 --- a/drivers/gpu/drm/vgem/Makefile +++ b/drivers/gpu/drm/vgem/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ccflags-y := -Iinclude/drm | 1 | ccflags-y := -Iinclude/drm |
| 2 | vgem-y := vgem_drv.o | 2 | vgem-y := vgem_drv.o vgem_fence.o |
| 3 | 3 | ||
| 4 | obj-$(CONFIG_DRM_VGEM) += vgem.o | 4 | obj-$(CONFIG_DRM_VGEM) += vgem.o |
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index 29c2aab3c1a7..c15bafb06665 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c | |||
| @@ -83,6 +83,34 @@ static const struct vm_operations_struct vgem_gem_vm_ops = { | |||
| 83 | .close = drm_gem_vm_close, | 83 | .close = drm_gem_vm_close, |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | static int vgem_open(struct drm_device *dev, struct drm_file *file) | ||
| 87 | { | ||
| 88 | struct vgem_file *vfile; | ||
| 89 | int ret; | ||
| 90 | |||
| 91 | vfile = kzalloc(sizeof(*vfile), GFP_KERNEL); | ||
| 92 | if (!vfile) | ||
| 93 | return -ENOMEM; | ||
| 94 | |||
| 95 | file->driver_priv = vfile; | ||
| 96 | |||
| 97 | ret = vgem_fence_open(vfile); | ||
| 98 | if (ret) { | ||
| 99 | kfree(vfile); | ||
| 100 | return ret; | ||
| 101 | } | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static void vgem_preclose(struct drm_device *dev, struct drm_file *file) | ||
| 107 | { | ||
| 108 | struct vgem_file *vfile = file->driver_priv; | ||
| 109 | |||
| 110 | vgem_fence_close(vfile); | ||
| 111 | kfree(vfile); | ||
| 112 | } | ||
| 113 | |||
| 86 | /* ioctls */ | 114 | /* ioctls */ |
| 87 | 115 | ||
| 88 | static struct drm_gem_object *vgem_gem_create(struct drm_device *dev, | 116 | static struct drm_gem_object *vgem_gem_create(struct drm_device *dev, |
| @@ -164,6 +192,8 @@ unref: | |||
| 164 | } | 192 | } |
| 165 | 193 | ||
| 166 | static struct drm_ioctl_desc vgem_ioctls[] = { | 194 | static struct drm_ioctl_desc vgem_ioctls[] = { |
| 195 | DRM_IOCTL_DEF_DRV(VGEM_FENCE_ATTACH, vgem_fence_attach_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | ||
| 196 | DRM_IOCTL_DEF_DRV(VGEM_FENCE_SIGNAL, vgem_fence_signal_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | ||
| 167 | }; | 197 | }; |
| 168 | 198 | ||
| 169 | static int vgem_mmap(struct file *filp, struct vm_area_struct *vma) | 199 | static int vgem_mmap(struct file *filp, struct vm_area_struct *vma) |
| @@ -271,9 +301,12 @@ static int vgem_prime_mmap(struct drm_gem_object *obj, | |||
| 271 | 301 | ||
| 272 | static struct drm_driver vgem_driver = { | 302 | static struct drm_driver vgem_driver = { |
| 273 | .driver_features = DRIVER_GEM | DRIVER_PRIME, | 303 | .driver_features = DRIVER_GEM | DRIVER_PRIME, |
| 304 | .open = vgem_open, | ||
| 305 | .preclose = vgem_preclose, | ||
| 274 | .gem_free_object_unlocked = vgem_gem_free_object, | 306 | .gem_free_object_unlocked = vgem_gem_free_object, |
| 275 | .gem_vm_ops = &vgem_gem_vm_ops, | 307 | .gem_vm_ops = &vgem_gem_vm_ops, |
| 276 | .ioctls = vgem_ioctls, | 308 | .ioctls = vgem_ioctls, |
| 309 | .num_ioctls = ARRAY_SIZE(vgem_ioctls), | ||
| 277 | .fops = &vgem_driver_fops, | 310 | .fops = &vgem_driver_fops, |
| 278 | 311 | ||
| 279 | .dumb_create = vgem_gem_dumb_create, | 312 | .dumb_create = vgem_gem_dumb_create, |
| @@ -328,5 +361,6 @@ module_init(vgem_init); | |||
| 328 | module_exit(vgem_exit); | 361 | module_exit(vgem_exit); |
| 329 | 362 | ||
| 330 | MODULE_AUTHOR("Red Hat, Inc."); | 363 | MODULE_AUTHOR("Red Hat, Inc."); |
| 364 | MODULE_AUTHOR("Intel Corporation"); | ||
| 331 | MODULE_DESCRIPTION(DRIVER_DESC); | 365 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 332 | MODULE_LICENSE("GPL and additional rights"); | 366 | MODULE_LICENSE("GPL and additional rights"); |
diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h index 988cbaae7588..1f8798ad329c 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.h +++ b/drivers/gpu/drm/vgem/vgem_drv.h | |||
| @@ -32,9 +32,25 @@ | |||
| 32 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
| 33 | #include <drm/drm_gem.h> | 33 | #include <drm/drm_gem.h> |
| 34 | 34 | ||
| 35 | #include <uapi/drm/vgem_drm.h> | ||
| 36 | |||
| 37 | struct vgem_file { | ||
| 38 | struct idr fence_idr; | ||
| 39 | struct mutex fence_mutex; | ||
| 40 | }; | ||
| 41 | |||
| 35 | #define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base) | 42 | #define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base) |
| 36 | struct drm_vgem_gem_object { | 43 | struct drm_vgem_gem_object { |
| 37 | struct drm_gem_object base; | 44 | struct drm_gem_object base; |
| 38 | }; | 45 | }; |
| 39 | 46 | ||
| 47 | int vgem_fence_open(struct vgem_file *file); | ||
| 48 | int vgem_fence_attach_ioctl(struct drm_device *dev, | ||
| 49 | void *data, | ||
| 50 | struct drm_file *file); | ||
| 51 | int vgem_fence_signal_ioctl(struct drm_device *dev, | ||
| 52 | void *data, | ||
| 53 | struct drm_file *file); | ||
| 54 | void vgem_fence_close(struct vgem_file *file); | ||
| 55 | |||
| 40 | #endif | 56 | #endif |
diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c new file mode 100644 index 000000000000..5c57c1ffa1f9 --- /dev/null +++ b/drivers/gpu/drm/vgem/vgem_fence.c | |||
| @@ -0,0 +1,283 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 Intel Corporation | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software") | ||
| 6 | * to deal in the software without restriction, including without limitation | ||
| 7 | * on the rights to use, copy, modify, merge, publish, distribute, sub | ||
| 8 | * license, and/or sell copies of the Software, and to permit persons to whom | ||
| 9 | * them Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice (including the next | ||
| 12 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 13 | * Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER | ||
| 19 | * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/dma-buf.h> | ||
| 24 | #include <linux/reservation.h> | ||
| 25 | |||
| 26 | #include "vgem_drv.h" | ||
| 27 | |||
| 28 | #define VGEM_FENCE_TIMEOUT (10*HZ) | ||
| 29 | |||
| 30 | struct vgem_fence { | ||
| 31 | struct fence base; | ||
| 32 | struct spinlock lock; | ||
| 33 | struct timer_list timer; | ||
| 34 | }; | ||
| 35 | |||
| 36 | static const char *vgem_fence_get_driver_name(struct fence *fence) | ||
| 37 | { | ||
| 38 | return "vgem"; | ||
| 39 | } | ||
| 40 | |||
| 41 | static const char *vgem_fence_get_timeline_name(struct fence *fence) | ||
| 42 | { | ||
| 43 | return "unbound"; | ||
| 44 | } | ||
| 45 | |||
| 46 | static bool vgem_fence_signaled(struct fence *fence) | ||
| 47 | { | ||
| 48 | return false; | ||
| 49 | } | ||
| 50 | |||
| 51 | static bool vgem_fence_enable_signaling(struct fence *fence) | ||
| 52 | { | ||
| 53 | return true; | ||
| 54 | } | ||
| 55 | |||
| 56 | static void vgem_fence_release(struct fence *base) | ||
| 57 | { | ||
| 58 | struct vgem_fence *fence = container_of(base, typeof(*fence), base); | ||
| 59 | |||
| 60 | del_timer_sync(&fence->timer); | ||
| 61 | fence_free(&fence->base); | ||
| 62 | } | ||
| 63 | |||
| 64 | static void vgem_fence_value_str(struct fence *fence, char *str, int size) | ||
| 65 | { | ||
| 66 | snprintf(str, size, "%u", fence->seqno); | ||
| 67 | } | ||
| 68 | |||
| 69 | static void vgem_fence_timeline_value_str(struct fence *fence, char *str, | ||
| 70 | int size) | ||
| 71 | { | ||
| 72 | snprintf(str, size, "%u", fence_is_signaled(fence) ? fence->seqno : 0); | ||
| 73 | } | ||
| 74 | |||
| 75 | static const struct fence_ops vgem_fence_ops = { | ||
| 76 | .get_driver_name = vgem_fence_get_driver_name, | ||
| 77 | .get_timeline_name = vgem_fence_get_timeline_name, | ||
| 78 | .enable_signaling = vgem_fence_enable_signaling, | ||
| 79 | .signaled = vgem_fence_signaled, | ||
| 80 | .wait = fence_default_wait, | ||
| 81 | .release = vgem_fence_release, | ||
| 82 | |||
| 83 | .fence_value_str = vgem_fence_value_str, | ||
| 84 | .timeline_value_str = vgem_fence_timeline_value_str, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static void vgem_fence_timeout(unsigned long data) | ||
| 88 | { | ||
| 89 | struct vgem_fence *fence = (struct vgem_fence *)data; | ||
| 90 | |||
| 91 | fence_signal(&fence->base); | ||
| 92 | } | ||
| 93 | |||
| 94 | static struct fence *vgem_fence_create(struct vgem_file *vfile, | ||
| 95 | unsigned int flags) | ||
| 96 | { | ||
| 97 | struct vgem_fence *fence; | ||
| 98 | |||
| 99 | fence = kzalloc(sizeof(*fence), GFP_KERNEL); | ||
| 100 | if (!fence) | ||
| 101 | return NULL; | ||
| 102 | |||
| 103 | spin_lock_init(&fence->lock); | ||
| 104 | fence_init(&fence->base, &vgem_fence_ops, &fence->lock, | ||
| 105 | fence_context_alloc(1), 1); | ||
| 106 | |||
| 107 | setup_timer(&fence->timer, vgem_fence_timeout, (unsigned long)fence); | ||
| 108 | |||
| 109 | /* We force the fence to expire within 10s to prevent driver hangs */ | ||
| 110 | mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); | ||
| 111 | |||
| 112 | return &fence->base; | ||
| 113 | } | ||
| 114 | |||
| 115 | static int attach_dmabuf(struct drm_device *dev, | ||
| 116 | struct drm_gem_object *obj) | ||
| 117 | { | ||
| 118 | struct dma_buf *dmabuf; | ||
| 119 | |||
| 120 | if (obj->dma_buf) | ||
| 121 | return 0; | ||
| 122 | |||
| 123 | dmabuf = dev->driver->gem_prime_export(dev, obj, 0); | ||
| 124 | if (IS_ERR(dmabuf)) | ||
| 125 | return PTR_ERR(dmabuf); | ||
| 126 | |||
| 127 | obj->dma_buf = dmabuf; | ||
| 128 | drm_gem_object_reference(obj); | ||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* | ||
| 133 | * vgem_fence_attach_ioctl (DRM_IOCTL_VGEM_FENCE_ATTACH): | ||
| 134 | * | ||
| 135 | * Create and attach a fence to the vGEM handle. This fence is then exposed | ||
| 136 | * via the dma-buf reservation object and visible to consumers of the exported | ||
| 137 | * dma-buf. If the flags contain VGEM_FENCE_WRITE, the fence indicates the | ||
| 138 | * vGEM buffer is being written to by the client and is exposed as an exclusive | ||
| 139 | * fence, otherwise the fence indicates the client is current reading from the | ||
| 140 | * buffer and all future writes should wait for the client to signal its | ||
| 141 | * completion. Note that if a conflicting fence is already on the dma-buf (i.e. | ||
| 142 | * an exclusive fence when adding a read, or any fence when adding a write), | ||
| 143 | * -EBUSY is reported. Serialisation between operations should be handled | ||
| 144 | * by waiting upon the dma-buf. | ||
| 145 | * | ||
| 146 | * This returns the handle for the new fence that must be signaled within 10 | ||
| 147 | * seconds (or otherwise it will automatically expire). See | ||
| 148 | * vgem_fence_signal_ioctl (DRM_IOCTL_VGEM_FENCE_SIGNAL). | ||
| 149 | * | ||
| 150 | * If the vGEM handle does not exist, vgem_fence_attach_ioctl returns -ENOENT. | ||
| 151 | */ | ||
| 152 | int vgem_fence_attach_ioctl(struct drm_device *dev, | ||
| 153 | void *data, | ||
| 154 | struct drm_file *file) | ||
| 155 | { | ||
| 156 | struct drm_vgem_fence_attach *arg = data; | ||
| 157 | struct vgem_file *vfile = file->driver_priv; | ||
| 158 | struct reservation_object *resv; | ||
| 159 | struct drm_gem_object *obj; | ||
| 160 | struct fence *fence; | ||
| 161 | int ret; | ||
| 162 | |||
| 163 | if (arg->flags & ~VGEM_FENCE_WRITE) | ||
| 164 | return -EINVAL; | ||
| 165 | |||
| 166 | if (arg->pad) | ||
| 167 | return -EINVAL; | ||
| 168 | |||
| 169 | obj = drm_gem_object_lookup(file, arg->handle); | ||
| 170 | if (!obj) | ||
| 171 | return -ENOENT; | ||
| 172 | |||
| 173 | ret = attach_dmabuf(dev, obj); | ||
| 174 | if (ret) | ||
| 175 | goto err; | ||
| 176 | |||
| 177 | fence = vgem_fence_create(vfile, arg->flags); | ||
| 178 | if (!fence) { | ||
| 179 | ret = -ENOMEM; | ||
| 180 | goto err; | ||
| 181 | } | ||
| 182 | |||
| 183 | /* Check for a conflicting fence */ | ||
| 184 | resv = obj->dma_buf->resv; | ||
| 185 | if (!reservation_object_test_signaled_rcu(resv, | ||
| 186 | arg->flags & VGEM_FENCE_WRITE)) { | ||
| 187 | ret = -EBUSY; | ||
| 188 | goto err_fence; | ||
| 189 | } | ||
| 190 | |||
| 191 | /* Expose the fence via the dma-buf */ | ||
| 192 | ret = 0; | ||
| 193 | mutex_lock(&resv->lock.base); | ||
| 194 | if (arg->flags & VGEM_FENCE_WRITE) | ||
| 195 | reservation_object_add_excl_fence(resv, fence); | ||
| 196 | else if ((ret = reservation_object_reserve_shared(resv)) == 0) | ||
| 197 | reservation_object_add_shared_fence(resv, fence); | ||
| 198 | mutex_unlock(&resv->lock.base); | ||
| 199 | |||
| 200 | /* Record the fence in our idr for later signaling */ | ||
| 201 | if (ret == 0) { | ||
| 202 | mutex_lock(&vfile->fence_mutex); | ||
| 203 | ret = idr_alloc(&vfile->fence_idr, fence, 1, 0, GFP_KERNEL); | ||
| 204 | mutex_unlock(&vfile->fence_mutex); | ||
| 205 | if (ret > 0) { | ||
| 206 | arg->out_fence = ret; | ||
| 207 | ret = 0; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | err_fence: | ||
| 211 | if (ret) { | ||
| 212 | fence_signal(fence); | ||
| 213 | fence_put(fence); | ||
| 214 | } | ||
| 215 | err: | ||
| 216 | drm_gem_object_unreference_unlocked(obj); | ||
| 217 | return ret; | ||
| 218 | } | ||
| 219 | |||
| 220 | /* | ||
| 221 | * vgem_fence_signal_ioctl (DRM_IOCTL_VGEM_FENCE_SIGNAL): | ||
| 222 | * | ||
| 223 | * Signal and consume a fence ealier attached to a vGEM handle using | ||
| 224 | * vgem_fence_attach_ioctl (DRM_IOCTL_VGEM_FENCE_ATTACH). | ||
| 225 | * | ||
| 226 | * All fences must be signaled within 10s of attachment or otherwise they | ||
| 227 | * will automatically expire (and a vgem_fence_signal_ioctl returns -ETIMEDOUT). | ||
| 228 | * | ||
| 229 | * Signaling a fence indicates to all consumers of the dma-buf that the | ||
| 230 | * client has completed the operation associated with the fence, and that the | ||
| 231 | * buffer is then ready for consumption. | ||
| 232 | * | ||
| 233 | * If the fence does not exist (or has already been signaled by the client), | ||
| 234 | * vgem_fence_signal_ioctl returns -ENOENT. | ||
| 235 | */ | ||
| 236 | int vgem_fence_signal_ioctl(struct drm_device *dev, | ||
| 237 | void *data, | ||
| 238 | struct drm_file *file) | ||
| 239 | { | ||
| 240 | struct vgem_file *vfile = file->driver_priv; | ||
| 241 | struct drm_vgem_fence_signal *arg = data; | ||
| 242 | struct fence *fence; | ||
| 243 | int ret = 0; | ||
| 244 | |||
| 245 | if (arg->flags) | ||
| 246 | return -EINVAL; | ||
| 247 | |||
| 248 | mutex_lock(&vfile->fence_mutex); | ||
| 249 | fence = idr_replace(&vfile->fence_idr, NULL, arg->fence); | ||
| 250 | mutex_unlock(&vfile->fence_mutex); | ||
| 251 | if (!fence) | ||
| 252 | return -ENOENT; | ||
| 253 | if (IS_ERR(fence)) | ||
| 254 | return PTR_ERR(fence); | ||
| 255 | |||
| 256 | if (fence_is_signaled(fence)) | ||
| 257 | ret = -ETIMEDOUT; | ||
| 258 | |||
| 259 | fence_signal(fence); | ||
| 260 | fence_put(fence); | ||
| 261 | return ret; | ||
| 262 | } | ||
| 263 | |||
| 264 | int vgem_fence_open(struct vgem_file *vfile) | ||
| 265 | { | ||
| 266 | mutex_init(&vfile->fence_mutex); | ||
| 267 | idr_init(&vfile->fence_idr); | ||
| 268 | |||
| 269 | return 0; | ||
| 270 | } | ||
| 271 | |||
| 272 | static int __vgem_fence_idr_fini(int id, void *p, void *data) | ||
| 273 | { | ||
| 274 | fence_signal(p); | ||
| 275 | fence_put(p); | ||
| 276 | return 0; | ||
| 277 | } | ||
| 278 | |||
| 279 | void vgem_fence_close(struct vgem_file *vfile) | ||
| 280 | { | ||
| 281 | idr_for_each(&vfile->fence_idr, __vgem_fence_idr_fini, vfile); | ||
| 282 | idr_destroy(&vfile->fence_idr); | ||
| 283 | } | ||
diff --git a/drivers/gpu/drm/virtio/Kconfig b/drivers/gpu/drm/virtio/Kconfig index 9983eadb81b6..e1afc3d3f8d9 100644 --- a/drivers/gpu/drm/virtio/Kconfig +++ b/drivers/gpu/drm/virtio/Kconfig | |||
| @@ -1,11 +1,7 @@ | |||
| 1 | config DRM_VIRTIO_GPU | 1 | config DRM_VIRTIO_GPU |
| 2 | tristate "Virtio GPU driver" | 2 | tristate "Virtio GPU driver" |
| 3 | depends on DRM && VIRTIO | 3 | depends on DRM && VIRTIO |
| 4 | select FB_SYS_FILLRECT | ||
| 5 | select FB_SYS_COPYAREA | ||
| 6 | select FB_SYS_IMAGEBLIT | ||
| 7 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
| 8 | select DRM_KMS_FB_HELPER | ||
| 9 | select DRM_TTM | 5 | select DRM_TTM |
| 10 | help | 6 | help |
| 11 | This is the virtual GPU driver for virtio. It can be used with | 7 | This is the virtual GPU driver for virtio. It can be used with |
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index ac758cdbc1bc..4e192aa2d021 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c | |||
| @@ -53,8 +53,7 @@ static void virtio_gpu_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
| 53 | struct virtio_gpu_framebuffer *virtio_gpu_fb | 53 | struct virtio_gpu_framebuffer *virtio_gpu_fb |
| 54 | = to_virtio_gpu_framebuffer(fb); | 54 | = to_virtio_gpu_framebuffer(fb); |
| 55 | 55 | ||
| 56 | if (virtio_gpu_fb->obj) | 56 | drm_gem_object_unreference_unlocked(virtio_gpu_fb->obj); |
| 57 | drm_gem_object_unreference_unlocked(virtio_gpu_fb->obj); | ||
| 58 | drm_framebuffer_cleanup(fb); | 57 | drm_framebuffer_cleanup(fb); |
| 59 | kfree(virtio_gpu_fb); | 58 | kfree(virtio_gpu_fb); |
| 60 | } | 59 | } |
| @@ -326,8 +325,7 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev, | |||
| 326 | ret = virtio_gpu_framebuffer_init(dev, virtio_gpu_fb, mode_cmd, obj); | 325 | ret = virtio_gpu_framebuffer_init(dev, virtio_gpu_fb, mode_cmd, obj); |
| 327 | if (ret) { | 326 | if (ret) { |
| 328 | kfree(virtio_gpu_fb); | 327 | kfree(virtio_gpu_fb); |
| 329 | if (obj) | 328 | drm_gem_object_unreference_unlocked(obj); |
| 330 | drm_gem_object_unreference_unlocked(obj); | ||
| 331 | return NULL; | 329 | return NULL; |
| 332 | } | 330 | } |
| 333 | 331 | ||
| @@ -348,7 +346,7 @@ static void vgdev_atomic_commit_tail(struct drm_atomic_state *state) | |||
| 348 | drm_atomic_helper_cleanup_planes(dev, state); | 346 | drm_atomic_helper_cleanup_planes(dev, state); |
| 349 | } | 347 | } |
| 350 | 348 | ||
| 351 | struct drm_mode_config_helper_funcs virtio_mode_config_helpers = { | 349 | static struct drm_mode_config_helper_funcs virtio_mode_config_helpers = { |
| 352 | .atomic_commit_tail = vgdev_atomic_commit_tail, | 350 | .atomic_commit_tail = vgdev_atomic_commit_tail, |
| 353 | }; | 351 | }; |
| 354 | 352 | ||
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c2fe2cffb809..d3778652e462 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -52,7 +52,6 @@ | |||
| 52 | #include <linux/poll.h> | 52 | #include <linux/poll.h> |
| 53 | #include <linux/ratelimit.h> | 53 | #include <linux/ratelimit.h> |
| 54 | #include <linux/sched.h> | 54 | #include <linux/sched.h> |
| 55 | #include <linux/seqlock.h> | ||
| 56 | #include <linux/slab.h> | 55 | #include <linux/slab.h> |
| 57 | #include <linux/types.h> | 56 | #include <linux/types.h> |
| 58 | #include <linux/vmalloc.h> | 57 | #include <linux/vmalloc.h> |
| @@ -87,6 +86,7 @@ struct drm_device_dma; | |||
| 87 | struct drm_dma_handle; | 86 | struct drm_dma_handle; |
| 88 | struct drm_gem_object; | 87 | struct drm_gem_object; |
| 89 | struct drm_master; | 88 | struct drm_master; |
| 89 | struct drm_vblank_crtc; | ||
| 90 | 90 | ||
| 91 | struct device_node; | 91 | struct device_node; |
| 92 | struct videomode; | 92 | struct videomode; |
| @@ -684,35 +684,6 @@ struct drm_minor { | |||
| 684 | struct mutex debugfs_lock; /* Protects debugfs_list. */ | 684 | struct mutex debugfs_lock; /* Protects debugfs_list. */ |
| 685 | }; | 685 | }; |
| 686 | 686 | ||
| 687 | |||
| 688 | struct drm_pending_vblank_event { | ||
| 689 | struct drm_pending_event base; | ||
| 690 | unsigned int pipe; | ||
| 691 | struct drm_event_vblank event; | ||
| 692 | }; | ||
| 693 | |||
| 694 | struct drm_vblank_crtc { | ||
| 695 | struct drm_device *dev; /* pointer to the drm_device */ | ||
| 696 | wait_queue_head_t queue; /**< VBLANK wait queue */ | ||
| 697 | struct timer_list disable_timer; /* delayed disable timer */ | ||
| 698 | |||
| 699 | seqlock_t seqlock; /* protects vblank count and time */ | ||
| 700 | |||
| 701 | u32 count; /* vblank counter */ | ||
| 702 | struct timeval time; /* vblank timestamp */ | ||
| 703 | |||
| 704 | atomic_t refcount; /* number of users of vblank interruptsper crtc */ | ||
| 705 | u32 last; /* protected by dev->vbl_lock, used */ | ||
| 706 | /* for wraparound handling */ | ||
| 707 | u32 last_wait; /* Last vblank seqno waited per CRTC */ | ||
| 708 | unsigned int inmodeset; /* Display driver is setting mode */ | ||
| 709 | unsigned int pipe; /* crtc index */ | ||
| 710 | int framedur_ns; /* frame/field duration in ns */ | ||
| 711 | int linedur_ns; /* line duration in ns */ | ||
| 712 | bool enabled; /* so we don't call enable more than | ||
| 713 | once per disable */ | ||
| 714 | }; | ||
| 715 | |||
| 716 | /** | 687 | /** |
| 717 | * DRM device structure. This structure represent a complete card that | 688 | * DRM device structure. This structure represent a complete card that |
| 718 | * may contain multiple heads. | 689 | * may contain multiple heads. |
| @@ -847,6 +818,8 @@ struct drm_device { | |||
| 847 | int switch_power_state; | 818 | int switch_power_state; |
| 848 | }; | 819 | }; |
| 849 | 820 | ||
| 821 | #include <drm/drm_irq.h> | ||
| 822 | |||
| 850 | #define DRM_SWITCH_POWER_ON 0 | 823 | #define DRM_SWITCH_POWER_ON 0 |
| 851 | #define DRM_SWITCH_POWER_OFF 1 | 824 | #define DRM_SWITCH_POWER_OFF 1 |
| 852 | #define DRM_SWITCH_POWER_CHANGING 2 | 825 | #define DRM_SWITCH_POWER_CHANGING 2 |
| @@ -933,56 +906,6 @@ void drm_clflush_virt_range(void *addr, unsigned long length); | |||
| 933 | * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. | 906 | * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. |
| 934 | */ | 907 | */ |
| 935 | 908 | ||
| 936 | /* IRQ support (drm_irq.h) */ | ||
| 937 | extern int drm_irq_install(struct drm_device *dev, int irq); | ||
| 938 | extern int drm_irq_uninstall(struct drm_device *dev); | ||
| 939 | |||
| 940 | extern int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); | ||
| 941 | extern int drm_wait_vblank(struct drm_device *dev, void *data, | ||
| 942 | struct drm_file *filp); | ||
| 943 | extern u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe); | ||
| 944 | extern u32 drm_crtc_vblank_count(struct drm_crtc *crtc); | ||
| 945 | extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, | ||
| 946 | struct timeval *vblanktime); | ||
| 947 | extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc, | ||
| 948 | struct drm_pending_vblank_event *e); | ||
| 949 | extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, | ||
| 950 | struct drm_pending_vblank_event *e); | ||
| 951 | extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); | ||
| 952 | extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc); | ||
| 953 | extern int drm_crtc_vblank_get(struct drm_crtc *crtc); | ||
| 954 | extern void drm_crtc_vblank_put(struct drm_crtc *crtc); | ||
| 955 | extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); | ||
| 956 | extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); | ||
| 957 | extern void drm_vblank_off(struct drm_device *dev, unsigned int pipe); | ||
| 958 | extern void drm_vblank_on(struct drm_device *dev, unsigned int pipe); | ||
| 959 | extern void drm_crtc_vblank_off(struct drm_crtc *crtc); | ||
| 960 | extern void drm_crtc_vblank_reset(struct drm_crtc *crtc); | ||
| 961 | extern void drm_crtc_vblank_on(struct drm_crtc *crtc); | ||
| 962 | extern void drm_vblank_cleanup(struct drm_device *dev); | ||
| 963 | extern u32 drm_accurate_vblank_count(struct drm_crtc *crtc); | ||
| 964 | extern u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe); | ||
| 965 | |||
| 966 | extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, | ||
| 967 | unsigned int pipe, int *max_error, | ||
| 968 | struct timeval *vblank_time, | ||
| 969 | unsigned flags, | ||
| 970 | const struct drm_display_mode *mode); | ||
| 971 | extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, | ||
| 972 | const struct drm_display_mode *mode); | ||
| 973 | |||
| 974 | /** | ||
| 975 | * drm_crtc_vblank_waitqueue - get vblank waitqueue for the CRTC | ||
| 976 | * @crtc: which CRTC's vblank waitqueue to retrieve | ||
| 977 | * | ||
| 978 | * This function returns a pointer to the vblank waitqueue for the CRTC. | ||
| 979 | * Drivers can use this to implement vblank waits using wait_event() & co. | ||
| 980 | */ | ||
| 981 | static inline wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc) | ||
| 982 | { | ||
| 983 | return &crtc->dev->vblank[drm_crtc_index(crtc)].queue; | ||
| 984 | } | ||
| 985 | |||
| 986 | /* Modesetting support */ | 909 | /* Modesetting support */ |
| 987 | extern void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe); | 910 | extern void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe); |
| 988 | extern void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe); | 911 | extern void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe); |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 9e6ab4a0c274..3edeaf88ebc0 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
| @@ -782,7 +782,10 @@ struct drm_crtc { | |||
| 782 | struct drm_plane *primary; | 782 | struct drm_plane *primary; |
| 783 | struct drm_plane *cursor; | 783 | struct drm_plane *cursor; |
| 784 | 784 | ||
| 785 | /* position inside the mode_config.list, can be used as a [] idx */ | 785 | /** |
| 786 | * @index: Position inside the mode_config.list, can be used as an array | ||
| 787 | * index. It is invariant over the lifetime of the CRTC. | ||
| 788 | */ | ||
| 786 | unsigned index; | 789 | unsigned index; |
| 787 | 790 | ||
| 788 | /* position of cursor plane on crtc */ | 791 | /* position of cursor plane on crtc */ |
| @@ -1209,7 +1212,10 @@ struct drm_encoder { | |||
| 1209 | char *name; | 1212 | char *name; |
| 1210 | int encoder_type; | 1213 | int encoder_type; |
| 1211 | 1214 | ||
| 1212 | /* position inside the mode_config.list, can be used as a [] idx */ | 1215 | /** |
| 1216 | * @index: Position inside the mode_config.list, can be used as an array | ||
| 1217 | * index. It is invariant over the lifetime of the encoder. | ||
| 1218 | */ | ||
| 1213 | unsigned index; | 1219 | unsigned index; |
| 1214 | 1220 | ||
| 1215 | uint32_t possible_crtcs; | 1221 | uint32_t possible_crtcs; |
| @@ -1240,7 +1246,6 @@ struct drm_encoder { | |||
| 1240 | * @head: list management | 1246 | * @head: list management |
| 1241 | * @base: base KMS object | 1247 | * @base: base KMS object |
| 1242 | * @name: human readable name, can be overwritten by the driver | 1248 | * @name: human readable name, can be overwritten by the driver |
| 1243 | * @connector_id: compacted connector id useful indexing arrays | ||
| 1244 | * @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h | 1249 | * @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h |
| 1245 | * @connector_type_id: index into connector type enum | 1250 | * @connector_type_id: index into connector type enum |
| 1246 | * @interlace_allowed: can this connector handle interlaced modes? | 1251 | * @interlace_allowed: can this connector handle interlaced modes? |
| @@ -1297,7 +1302,15 @@ struct drm_connector { | |||
| 1297 | struct drm_mode_object base; | 1302 | struct drm_mode_object base; |
| 1298 | 1303 | ||
| 1299 | char *name; | 1304 | char *name; |
| 1300 | int connector_id; | 1305 | |
| 1306 | /** | ||
| 1307 | * @index: Compacted connector index, which matches the position inside | ||
| 1308 | * the mode_config.list for drivers not supporting hot-add/removing. Can | ||
| 1309 | * be used as an array index. It is invariant over the lifetime of the | ||
| 1310 | * connector. | ||
| 1311 | */ | ||
| 1312 | unsigned index; | ||
| 1313 | |||
| 1301 | int connector_type; | 1314 | int connector_type; |
| 1302 | int connector_type_id; | 1315 | int connector_type_id; |
| 1303 | bool interlace_allowed; | 1316 | bool interlace_allowed; |
| @@ -1710,7 +1723,10 @@ struct drm_plane { | |||
| 1710 | 1723 | ||
| 1711 | enum drm_plane_type type; | 1724 | enum drm_plane_type type; |
| 1712 | 1725 | ||
| 1713 | /* position inside the mode_config.list, can be used as a [] idx */ | 1726 | /** |
| 1727 | * @index: Position inside the mode_config.list, can be used as an array | ||
| 1728 | * index. It is invariant over the lifetime of the plane. | ||
| 1729 | */ | ||
| 1714 | unsigned index; | 1730 | unsigned index; |
| 1715 | 1731 | ||
| 1716 | const struct drm_plane_helper_funcs *helper_private; | 1732 | const struct drm_plane_helper_funcs *helper_private; |
| @@ -2318,8 +2334,6 @@ struct drm_mode_config_funcs { | |||
| 2318 | * @fb_lock: mutex to protect fb state and lists | 2334 | * @fb_lock: mutex to protect fb state and lists |
| 2319 | * @num_fb: number of fbs available | 2335 | * @num_fb: number of fbs available |
| 2320 | * @fb_list: list of framebuffers available | 2336 | * @fb_list: list of framebuffers available |
| 2321 | * @num_connector: number of connectors on this device | ||
| 2322 | * @connector_list: list of connector objects | ||
| 2323 | * @num_encoder: number of encoders on this device | 2337 | * @num_encoder: number of encoders on this device |
| 2324 | * @encoder_list: list of encoder objects | 2338 | * @encoder_list: list of encoder objects |
| 2325 | * @num_overlay_plane: number of overlay planes on this device | 2339 | * @num_overlay_plane: number of overlay planes on this device |
| @@ -2341,18 +2355,8 @@ struct drm_mode_config_funcs { | |||
| 2341 | * @property_blob_list: list of all the blob property objects | 2355 | * @property_blob_list: list of all the blob property objects |
| 2342 | * @blob_lock: mutex for blob property allocation and management | 2356 | * @blob_lock: mutex for blob property allocation and management |
| 2343 | * @*_property: core property tracking | 2357 | * @*_property: core property tracking |
| 2344 | * @degamma_lut_property: LUT used to convert the framebuffer's colors to linear | ||
| 2345 | * gamma | ||
| 2346 | * @degamma_lut_size_property: size of the degamma LUT as supported by the | ||
| 2347 | * driver (read-only) | ||
| 2348 | * @ctm_property: Matrix used to convert colors after the lookup in the | ||
| 2349 | * degamma LUT | ||
| 2350 | * @gamma_lut_property: LUT used to convert the colors, after the CSC matrix, to | ||
| 2351 | * the gamma space of the connected screen (read-only) | ||
| 2352 | * @gamma_lut_size_property: size of the gamma LUT as supported by the driver | ||
| 2353 | * @preferred_depth: preferred RBG pixel depth, used by fb helpers | 2358 | * @preferred_depth: preferred RBG pixel depth, used by fb helpers |
| 2354 | * @prefer_shadow: hint to userspace to prefer shadow-fb rendering | 2359 | * @prefer_shadow: hint to userspace to prefer shadow-fb rendering |
| 2355 | * @async_page_flip: does this device support async flips on the primary plane? | ||
| 2356 | * @cursor_width: hint to userspace for max cursor width | 2360 | * @cursor_width: hint to userspace for max cursor width |
| 2357 | * @cursor_height: hint to userspace for max cursor height | 2361 | * @cursor_height: hint to userspace for max cursor height |
| 2358 | * @helper_private: mid-layer private data | 2362 | * @helper_private: mid-layer private data |
| @@ -2394,8 +2398,17 @@ struct drm_mode_config { | |||
| 2394 | int num_fb; | 2398 | int num_fb; |
| 2395 | struct list_head fb_list; | 2399 | struct list_head fb_list; |
| 2396 | 2400 | ||
| 2401 | /** | ||
| 2402 | * @num_connector: Number of connectors on this device. | ||
| 2403 | */ | ||
| 2397 | int num_connector; | 2404 | int num_connector; |
| 2405 | /** | ||
| 2406 | * @connector_ida: ID allocator for connector indices. | ||
| 2407 | */ | ||
| 2398 | struct ida connector_ida; | 2408 | struct ida connector_ida; |
| 2409 | /** | ||
| 2410 | * @connector_list: List of connector objects. | ||
| 2411 | */ | ||
| 2399 | struct list_head connector_list; | 2412 | struct list_head connector_list; |
| 2400 | int num_encoder; | 2413 | int num_encoder; |
| 2401 | struct list_head encoder_list; | 2414 | struct list_head encoder_list; |
| @@ -2430,64 +2443,238 @@ struct drm_mode_config { | |||
| 2430 | 2443 | ||
| 2431 | /* pointers to standard properties */ | 2444 | /* pointers to standard properties */ |
| 2432 | struct list_head property_blob_list; | 2445 | struct list_head property_blob_list; |
| 2446 | /** | ||
| 2447 | * @edid_property: Default connector property to hold the EDID of the | ||
| 2448 | * currently connected sink, if any. | ||
| 2449 | */ | ||
| 2433 | struct drm_property *edid_property; | 2450 | struct drm_property *edid_property; |
| 2451 | /** | ||
| 2452 | * @dpms_property: Default connector property to control the | ||
| 2453 | * connector's DPMS state. | ||
| 2454 | */ | ||
| 2434 | struct drm_property *dpms_property; | 2455 | struct drm_property *dpms_property; |
| 2456 | /** | ||
| 2457 | * @path_property: Default connector property to hold the DP MST path | ||
| 2458 | * for the port. | ||
| 2459 | */ | ||
| 2435 | struct drm_property *path_property; | 2460 | struct drm_property *path_property; |
| 2461 | /** | ||
| 2462 | * @tile_property: Default connector property to store the tile | ||
| 2463 | * position of a tiled screen, for sinks which need to be driven with | ||
| 2464 | * multiple CRTCs. | ||
| 2465 | */ | ||
| 2436 | struct drm_property *tile_property; | 2466 | struct drm_property *tile_property; |
| 2467 | /** | ||
| 2468 | * @plane_type_property: Default plane property to differentiate | ||
| 2469 | * CURSOR, PRIMARY and OVERLAY legacy uses of planes. | ||
| 2470 | */ | ||
| 2437 | struct drm_property *plane_type_property; | 2471 | struct drm_property *plane_type_property; |
| 2472 | /** | ||
| 2473 | * @rotation_property: Optional property for planes or CRTCs to specifiy | ||
| 2474 | * rotation. | ||
| 2475 | */ | ||
| 2438 | struct drm_property *rotation_property; | 2476 | struct drm_property *rotation_property; |
| 2477 | /** | ||
| 2478 | * @prop_src_x: Default atomic plane property for the plane source | ||
| 2479 | * position in the connected &drm_framebuffer. | ||
| 2480 | */ | ||
| 2439 | struct drm_property *prop_src_x; | 2481 | struct drm_property *prop_src_x; |
| 2482 | /** | ||
| 2483 | * @prop_src_y: Default atomic plane property for the plane source | ||
| 2484 | * position in the connected &drm_framebuffer. | ||
| 2485 | */ | ||
| 2440 | struct drm_property *prop_src_y; | 2486 | struct drm_property *prop_src_y; |
| 2487 | /** | ||
| 2488 | * @prop_src_w: Default atomic plane property for the plane source | ||
| 2489 | * position in the connected &drm_framebuffer. | ||
| 2490 | */ | ||
| 2441 | struct drm_property *prop_src_w; | 2491 | struct drm_property *prop_src_w; |
| 2492 | /** | ||
| 2493 | * @prop_src_h: Default atomic plane property for the plane source | ||
| 2494 | * position in the connected &drm_framebuffer. | ||
| 2495 | */ | ||
| 2442 | struct drm_property *prop_src_h; | 2496 | struct drm_property *prop_src_h; |
| 2497 | /** | ||
| 2498 | * @prop_crtc_x: Default atomic plane property for the plane destination | ||
| 2499 | * position in the &drm_crtc is is being shown on. | ||
| 2500 | */ | ||
| 2443 | struct drm_property *prop_crtc_x; | 2501 | struct drm_property *prop_crtc_x; |
| 2502 | /** | ||
| 2503 | * @prop_crtc_y: Default atomic plane property for the plane destination | ||
| 2504 | * position in the &drm_crtc is is being shown on. | ||
| 2505 | */ | ||
| 2444 | struct drm_property *prop_crtc_y; | 2506 | struct drm_property *prop_crtc_y; |
| 2507 | /** | ||
| 2508 | * @prop_crtc_w: Default atomic plane property for the plane destination | ||
| 2509 | * position in the &drm_crtc is is being shown on. | ||
| 2510 | */ | ||
| 2445 | struct drm_property *prop_crtc_w; | 2511 | struct drm_property *prop_crtc_w; |
| 2512 | /** | ||
| 2513 | * @prop_crtc_h: Default atomic plane property for the plane destination | ||
| 2514 | * position in the &drm_crtc is is being shown on. | ||
| 2515 | */ | ||
| 2446 | struct drm_property *prop_crtc_h; | 2516 | struct drm_property *prop_crtc_h; |
| 2517 | /** | ||
| 2518 | * @prop_fb_id: Default atomic plane property to specify the | ||
| 2519 | * &drm_framebuffer. | ||
| 2520 | */ | ||
| 2447 | struct drm_property *prop_fb_id; | 2521 | struct drm_property *prop_fb_id; |
| 2522 | /** | ||
| 2523 | * @prop_crtc_id: Default atomic plane property to specify the | ||
| 2524 | * &drm_crtc. | ||
| 2525 | */ | ||
| 2448 | struct drm_property *prop_crtc_id; | 2526 | struct drm_property *prop_crtc_id; |
| 2527 | /** | ||
| 2528 | * @prop_active: Default atomic CRTC property to control the active | ||
| 2529 | * state, which is the simplified implementation for DPMS in atomic | ||
| 2530 | * drivers. | ||
| 2531 | */ | ||
| 2449 | struct drm_property *prop_active; | 2532 | struct drm_property *prop_active; |
| 2533 | /** | ||
| 2534 | * @prop_mode_id: Default atomic CRTC property to set the mode for a | ||
| 2535 | * CRTC. A 0 mode implies that the CRTC is entirely disabled - all | ||
| 2536 | * connectors must be of and active must be set to disabled, too. | ||
| 2537 | */ | ||
| 2450 | struct drm_property *prop_mode_id; | 2538 | struct drm_property *prop_mode_id; |
| 2451 | 2539 | ||
| 2452 | /* DVI-I properties */ | 2540 | /** |
| 2541 | * @dvi_i_subconnector_property: Optional DVI-I property to | ||
| 2542 | * differentiate between analog or digital mode. | ||
| 2543 | */ | ||
| 2453 | struct drm_property *dvi_i_subconnector_property; | 2544 | struct drm_property *dvi_i_subconnector_property; |
| 2545 | /** | ||
| 2546 | * @dvi_i_select_subconnector_property: Optional DVI-I property to | ||
| 2547 | * select between analog or digital mode. | ||
| 2548 | */ | ||
| 2454 | struct drm_property *dvi_i_select_subconnector_property; | 2549 | struct drm_property *dvi_i_select_subconnector_property; |
| 2455 | 2550 | ||
| 2456 | /* TV properties */ | 2551 | /** |
| 2552 | * @tv_subconnector_property: Optional TV property to differentiate | ||
| 2553 | * between different TV connector types. | ||
| 2554 | */ | ||
| 2457 | struct drm_property *tv_subconnector_property; | 2555 | struct drm_property *tv_subconnector_property; |
| 2556 | /** | ||
| 2557 | * @tv_select_subconnector_property: Optional TV property to select | ||
| 2558 | * between different TV connector types. | ||
| 2559 | */ | ||
| 2458 | struct drm_property *tv_select_subconnector_property; | 2560 | struct drm_property *tv_select_subconnector_property; |
| 2561 | /** | ||
| 2562 | * @tv_mode_property: Optional TV property to select | ||
| 2563 | * the output TV mode. | ||
| 2564 | */ | ||
| 2459 | struct drm_property *tv_mode_property; | 2565 | struct drm_property *tv_mode_property; |
| 2566 | /** | ||
| 2567 | * @tv_left_margin_property: Optional TV property to set the left | ||
| 2568 | * margin. | ||
| 2569 | */ | ||
| 2460 | struct drm_property *tv_left_margin_property; | 2570 | struct drm_property *tv_left_margin_property; |
| 2571 | /** | ||
| 2572 | * @tv_right_margin_property: Optional TV property to set the right | ||
| 2573 | * margin. | ||
| 2574 | */ | ||
| 2461 | struct drm_property *tv_right_margin_property; | 2575 | struct drm_property *tv_right_margin_property; |
| 2576 | /** | ||
| 2577 | * @tv_top_margin_property: Optional TV property to set the right | ||
| 2578 | * margin. | ||
| 2579 | */ | ||
| 2462 | struct drm_property *tv_top_margin_property; | 2580 | struct drm_property *tv_top_margin_property; |
| 2581 | /** | ||
| 2582 | * @tv_bottom_margin_property: Optional TV property to set the right | ||
| 2583 | * margin. | ||
| 2584 | */ | ||
| 2463 | struct drm_property *tv_bottom_margin_property; | 2585 | struct drm_property *tv_bottom_margin_property; |
| 2586 | /** | ||
| 2587 | * @tv_brightness_property: Optional TV property to set the | ||
| 2588 | * brightness. | ||
| 2589 | */ | ||
| 2464 | struct drm_property *tv_brightness_property; | 2590 | struct drm_property *tv_brightness_property; |
| 2591 | /** | ||
| 2592 | * @tv_contrast_property: Optional TV property to set the | ||
| 2593 | * contrast. | ||
| 2594 | */ | ||
| 2465 | struct drm_property *tv_contrast_property; | 2595 | struct drm_property *tv_contrast_property; |
| 2596 | /** | ||
| 2597 | * @tv_flicker_reduction_property: Optional TV property to control the | ||
| 2598 | * flicker reduction mode. | ||
| 2599 | */ | ||
| 2466 | struct drm_property *tv_flicker_reduction_property; | 2600 | struct drm_property *tv_flicker_reduction_property; |
| 2601 | /** | ||
| 2602 | * @tv_overscan_property: Optional TV property to control the overscan | ||
| 2603 | * setting. | ||
| 2604 | */ | ||
| 2467 | struct drm_property *tv_overscan_property; | 2605 | struct drm_property *tv_overscan_property; |
| 2606 | /** | ||
| 2607 | * @tv_saturation_property: Optional TV property to set the | ||
| 2608 | * saturation. | ||
| 2609 | */ | ||
| 2468 | struct drm_property *tv_saturation_property; | 2610 | struct drm_property *tv_saturation_property; |
| 2611 | /** | ||
| 2612 | * @tv_hue_property: Optional TV property to set the hue. | ||
| 2613 | */ | ||
| 2469 | struct drm_property *tv_hue_property; | 2614 | struct drm_property *tv_hue_property; |
| 2470 | 2615 | ||
| 2471 | /* Optional properties */ | 2616 | /** |
| 2617 | * @scaling_mode_property: Optional connector property to control the | ||
| 2618 | * upscaling, mostly used for built-in panels. | ||
| 2619 | */ | ||
| 2472 | struct drm_property *scaling_mode_property; | 2620 | struct drm_property *scaling_mode_property; |
| 2621 | /** | ||
| 2622 | * @aspect_ratio_property: Optional connector property to control the | ||
| 2623 | * HDMI infoframe aspect ratio setting. | ||
| 2624 | */ | ||
| 2473 | struct drm_property *aspect_ratio_property; | 2625 | struct drm_property *aspect_ratio_property; |
| 2626 | /** | ||
| 2627 | * @dirty_info_property: Optional connector property to give userspace a | ||
| 2628 | * hint that the DIRTY_FB ioctl should be used. | ||
| 2629 | */ | ||
| 2474 | struct drm_property *dirty_info_property; | 2630 | struct drm_property *dirty_info_property; |
| 2475 | 2631 | ||
| 2476 | /* Optional color correction properties */ | 2632 | /** |
| 2633 | * @degamma_lut_property: Optional CRTC property to set the LUT used to | ||
| 2634 | * convert the framebuffer's colors to linear gamma. | ||
| 2635 | */ | ||
| 2477 | struct drm_property *degamma_lut_property; | 2636 | struct drm_property *degamma_lut_property; |
| 2637 | /** | ||
| 2638 | * @degamma_lut_size_property: Optional CRTC property for the size of | ||
| 2639 | * the degamma LUT as supported by the driver (read-only). | ||
| 2640 | */ | ||
| 2478 | struct drm_property *degamma_lut_size_property; | 2641 | struct drm_property *degamma_lut_size_property; |
| 2642 | /** | ||
| 2643 | * @ctm_property: Optional CRTC property to set the | ||
| 2644 | * matrix used to convert colors after the lookup in the | ||
| 2645 | * degamma LUT. | ||
| 2646 | */ | ||
| 2479 | struct drm_property *ctm_property; | 2647 | struct drm_property *ctm_property; |
| 2648 | /** | ||
| 2649 | * @gamma_lut_property: Optional CRTC property to set the LUT used to | ||
| 2650 | * convert the colors, after the CTM matrix, to the gamma space of the | ||
| 2651 | * connected screen. | ||
| 2652 | */ | ||
| 2480 | struct drm_property *gamma_lut_property; | 2653 | struct drm_property *gamma_lut_property; |
| 2654 | /** | ||
| 2655 | * @gamma_lut_size_property: Optional CRTC property for the size of the | ||
| 2656 | * gamma LUT as supported by the driver (read-only). | ||
| 2657 | */ | ||
| 2481 | struct drm_property *gamma_lut_size_property; | 2658 | struct drm_property *gamma_lut_size_property; |
| 2482 | 2659 | ||
| 2483 | /* properties for virtual machine layout */ | 2660 | /** |
| 2661 | * @suggested_x_property: Optional connector property with a hint for | ||
| 2662 | * the position of the output on the host's screen. | ||
| 2663 | */ | ||
| 2484 | struct drm_property *suggested_x_property; | 2664 | struct drm_property *suggested_x_property; |
| 2665 | /** | ||
| 2666 | * @suggested_y_property: Optional connector property with a hint for | ||
| 2667 | * the position of the output on the host's screen. | ||
| 2668 | */ | ||
| 2485 | struct drm_property *suggested_y_property; | 2669 | struct drm_property *suggested_y_property; |
| 2486 | 2670 | ||
| 2487 | /* dumb ioctl parameters */ | 2671 | /* dumb ioctl parameters */ |
| 2488 | uint32_t preferred_depth, prefer_shadow; | 2672 | uint32_t preferred_depth, prefer_shadow; |
| 2489 | 2673 | ||
| 2490 | /* whether async page flip is supported or not */ | 2674 | /** |
| 2675 | * @async_page_flip: Does this device support async flips on the primary | ||
| 2676 | * plane? | ||
| 2677 | */ | ||
| 2491 | bool async_page_flip; | 2678 | bool async_page_flip; |
| 2492 | 2679 | ||
| 2493 | /** | 2680 | /** |
| @@ -2584,12 +2771,9 @@ void drm_connector_unregister(struct drm_connector *connector); | |||
| 2584 | extern void drm_connector_cleanup(struct drm_connector *connector); | 2771 | extern void drm_connector_cleanup(struct drm_connector *connector); |
| 2585 | static inline unsigned drm_connector_index(struct drm_connector *connector) | 2772 | static inline unsigned drm_connector_index(struct drm_connector *connector) |
| 2586 | { | 2773 | { |
| 2587 | return connector->connector_id; | 2774 | return connector->index; |
| 2588 | } | 2775 | } |
| 2589 | 2776 | ||
| 2590 | /* helpers to {un}register all connectors from sysfs for device */ | ||
| 2591 | extern void drm_connector_unregister_all(struct drm_device *dev); | ||
| 2592 | |||
| 2593 | extern __printf(5, 6) | 2777 | extern __printf(5, 6) |
| 2594 | int drm_encoder_init(struct drm_device *dev, | 2778 | int drm_encoder_init(struct drm_device *dev, |
| 2595 | struct drm_encoder *encoder, | 2779 | struct drm_encoder *encoder, |
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 4d85cf2874af..72dee1213268 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h | |||
| @@ -747,7 +747,14 @@ struct drm_dp_aux { | |||
| 747 | struct mutex hw_mutex; | 747 | struct mutex hw_mutex; |
| 748 | ssize_t (*transfer)(struct drm_dp_aux *aux, | 748 | ssize_t (*transfer)(struct drm_dp_aux *aux, |
| 749 | struct drm_dp_aux_msg *msg); | 749 | struct drm_dp_aux_msg *msg); |
| 750 | unsigned i2c_nack_count, i2c_defer_count; | 750 | /** |
| 751 | * @i2c_nack_count: Counts I2C NACKs, used for DP validation. | ||
| 752 | */ | ||
| 753 | unsigned i2c_nack_count; | ||
| 754 | /** | ||
| 755 | * @i2c_defer_count: Counts I2C DEFERs, used for DP validation. | ||
| 756 | */ | ||
| 757 | unsigned i2c_defer_count; | ||
| 751 | }; | 758 | }; |
| 752 | 759 | ||
| 753 | ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, | 760 | ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, |
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index fdb47051d549..003207670597 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h | |||
| @@ -87,7 +87,15 @@ struct drm_dp_mst_port { | |||
| 87 | struct drm_connector *connector; | 87 | struct drm_connector *connector; |
| 88 | struct drm_dp_mst_topology_mgr *mgr; | 88 | struct drm_dp_mst_topology_mgr *mgr; |
| 89 | 89 | ||
| 90 | struct edid *cached_edid; /* for DP logical ports - make tiling work */ | 90 | /** |
| 91 | * @cached_edid: for DP logical ports - make tiling work by ensuring | ||
| 92 | * that the EDID for all connectors is read immediately. | ||
| 93 | */ | ||
| 94 | struct edid *cached_edid; | ||
| 95 | /** | ||
| 96 | * @has_audio: Tracks whether the sink connector to this port is | ||
| 97 | * audio-capable. | ||
| 98 | */ | ||
| 91 | bool has_audio; | 99 | bool has_audio; |
| 92 | }; | 100 | }; |
| 93 | 101 | ||
| @@ -397,71 +405,154 @@ struct drm_dp_payload { | |||
| 397 | 405 | ||
| 398 | /** | 406 | /** |
| 399 | * struct drm_dp_mst_topology_mgr - DisplayPort MST manager | 407 | * struct drm_dp_mst_topology_mgr - DisplayPort MST manager |
| 400 | * @dev: device pointer for adding i2c devices etc. | ||
| 401 | * @cbs: callbacks for connector addition and destruction. | ||
| 402 | * @max_dpcd_transaction_bytes - maximum number of bytes to read/write in one go. | ||
| 403 | * @aux: aux channel for the DP connector. | ||
| 404 | * @max_payloads: maximum number of payloads the GPU can generate. | ||
| 405 | * @conn_base_id: DRM connector ID this mgr is connected to. | ||
| 406 | * @down_rep_recv: msg receiver state for down replies. | ||
| 407 | * @up_req_recv: msg receiver state for up requests. | ||
| 408 | * @lock: protects mst state, primary, dpcd. | ||
| 409 | * @mst_state: if this manager is enabled for an MST capable port. | ||
| 410 | * @mst_primary: pointer to the primary branch device. | ||
| 411 | * @dpcd: cache of DPCD for primary port. | ||
| 412 | * @pbn_div: PBN to slots divisor. | ||
| 413 | * | 408 | * |
| 414 | * This struct represents the toplevel displayport MST topology manager. | 409 | * This struct represents the toplevel displayport MST topology manager. |
| 415 | * There should be one instance of this for every MST capable DP connector | 410 | * There should be one instance of this for every MST capable DP connector |
| 416 | * on the GPU. | 411 | * on the GPU. |
| 417 | */ | 412 | */ |
| 418 | struct drm_dp_mst_topology_mgr { | 413 | struct drm_dp_mst_topology_mgr { |
| 419 | 414 | /** | |
| 415 | * @dev: device pointer for adding i2c devices etc. | ||
| 416 | */ | ||
| 420 | struct device *dev; | 417 | struct device *dev; |
| 418 | /** | ||
| 419 | * @cbs: callbacks for connector addition and destruction. | ||
| 420 | */ | ||
| 421 | const struct drm_dp_mst_topology_cbs *cbs; | 421 | const struct drm_dp_mst_topology_cbs *cbs; |
| 422 | /** | ||
| 423 | * @max_dpcd_transaction_bytes: maximum number of bytes to read/write | ||
| 424 | * in one go. | ||
| 425 | */ | ||
| 422 | int max_dpcd_transaction_bytes; | 426 | int max_dpcd_transaction_bytes; |
| 423 | struct drm_dp_aux *aux; /* auxch for this topology mgr to use */ | 427 | /** |
| 428 | * @aux: AUX channel for the DP MST connector this topolgy mgr is | ||
| 429 | * controlling. | ||
| 430 | */ | ||
| 431 | struct drm_dp_aux *aux; | ||
| 432 | /** | ||
| 433 | * @max_payloads: maximum number of payloads the GPU can generate. | ||
| 434 | */ | ||
| 424 | int max_payloads; | 435 | int max_payloads; |
| 436 | /** | ||
| 437 | * @conn_base_id: DRM connector ID this mgr is connected to. Only used | ||
| 438 | * to build the MST connector path value. | ||
| 439 | */ | ||
| 425 | int conn_base_id; | 440 | int conn_base_id; |
| 426 | 441 | ||
| 427 | /* only ever accessed from the workqueue - which should be serialised */ | 442 | /** |
| 443 | * @down_rep_recv: Message receiver state for down replies. This and | ||
| 444 | * @up_req_recv are only ever access from the work item, which is | ||
| 445 | * serialised. | ||
| 446 | */ | ||
| 428 | struct drm_dp_sideband_msg_rx down_rep_recv; | 447 | struct drm_dp_sideband_msg_rx down_rep_recv; |
| 448 | /** | ||
| 449 | * @up_req_recv: Message receiver state for up requests. This and | ||
| 450 | * @down_rep_recv are only ever access from the work item, which is | ||
| 451 | * serialised. | ||
| 452 | */ | ||
| 429 | struct drm_dp_sideband_msg_rx up_req_recv; | 453 | struct drm_dp_sideband_msg_rx up_req_recv; |
| 430 | 454 | ||
| 431 | /* pointer to info about the initial MST device */ | 455 | /** |
| 432 | struct mutex lock; /* protects mst_state + primary + dpcd */ | 456 | * @lock: protects mst state, primary, dpcd. |
| 457 | */ | ||
| 458 | struct mutex lock; | ||
| 433 | 459 | ||
| 460 | /** | ||
| 461 | * @mst_state: If this manager is enabled for an MST capable port. False | ||
| 462 | * if no MST sink/branch devices is connected. | ||
| 463 | */ | ||
| 434 | bool mst_state; | 464 | bool mst_state; |
| 465 | /** | ||
| 466 | * @mst_primary: Pointer to the primary/first branch device. | ||
| 467 | */ | ||
| 435 | struct drm_dp_mst_branch *mst_primary; | 468 | struct drm_dp_mst_branch *mst_primary; |
| 436 | 469 | ||
| 470 | /** | ||
| 471 | * @dpcd: Cache of DPCD for primary port. | ||
| 472 | */ | ||
| 437 | u8 dpcd[DP_RECEIVER_CAP_SIZE]; | 473 | u8 dpcd[DP_RECEIVER_CAP_SIZE]; |
| 474 | /** | ||
| 475 | * @sink_count: Sink count from DEVICE_SERVICE_IRQ_VECTOR_ESI0. | ||
| 476 | */ | ||
| 438 | u8 sink_count; | 477 | u8 sink_count; |
| 478 | /** | ||
| 479 | * @pbn_div: PBN to slots divisor. | ||
| 480 | */ | ||
| 439 | int pbn_div; | 481 | int pbn_div; |
| 482 | /** | ||
| 483 | * @total_slots: Total slots that can be allocated. | ||
| 484 | */ | ||
| 440 | int total_slots; | 485 | int total_slots; |
| 486 | /** | ||
| 487 | * @avail_slots: Still available slots that can be allocated. | ||
| 488 | */ | ||
| 441 | int avail_slots; | 489 | int avail_slots; |
| 490 | /** | ||
| 491 | * @total_pbn: Total PBN count. | ||
| 492 | */ | ||
| 442 | int total_pbn; | 493 | int total_pbn; |
| 443 | 494 | ||
| 444 | /* messages to be transmitted */ | 495 | /** |
| 445 | /* qlock protects the upq/downq and in_progress, | 496 | * @qlock: protects @tx_msg_downq, the tx_slots in struct |
| 446 | the mstb tx_slots and txmsg->state once they are queued */ | 497 | * &drm_dp_mst_branch and txmsg->state once they are queued |
| 498 | */ | ||
| 447 | struct mutex qlock; | 499 | struct mutex qlock; |
| 500 | /** | ||
| 501 | * @tx_msg_downq: List of pending down replies. | ||
| 502 | */ | ||
| 448 | struct list_head tx_msg_downq; | 503 | struct list_head tx_msg_downq; |
| 449 | bool tx_down_in_progress; | ||
| 450 | 504 | ||
| 451 | /* payload info + lock for it */ | 505 | /** |
| 506 | * @payload_lock: Protect payload information. | ||
| 507 | */ | ||
| 452 | struct mutex payload_lock; | 508 | struct mutex payload_lock; |
| 509 | /** | ||
| 510 | * @proposed_vcpis: Array of pointers for the new VCPI allocation. The | ||
| 511 | * VCPI structure itself is embedded into the corresponding | ||
| 512 | * &drm_dp_mst_port structure. | ||
| 513 | */ | ||
| 453 | struct drm_dp_vcpi **proposed_vcpis; | 514 | struct drm_dp_vcpi **proposed_vcpis; |
| 515 | /** | ||
| 516 | * @payloads: Array of payloads. | ||
| 517 | */ | ||
| 454 | struct drm_dp_payload *payloads; | 518 | struct drm_dp_payload *payloads; |
| 519 | /** | ||
| 520 | * @payload_mask: Elements of @payloads actually in use. Since | ||
| 521 | * reallocation of active outputs isn't possible gaps can be created by | ||
| 522 | * disabling outputs out of order compared to how they've been enabled. | ||
| 523 | */ | ||
| 455 | unsigned long payload_mask; | 524 | unsigned long payload_mask; |
| 525 | /** | ||
| 526 | * @vcpi_mask: Similar to @payload_mask, but for @proposed_vcpis. | ||
| 527 | */ | ||
| 456 | unsigned long vcpi_mask; | 528 | unsigned long vcpi_mask; |
| 457 | 529 | ||
| 530 | /** | ||
| 531 | * @tx_waitq: Wait to queue stall for the tx worker. | ||
| 532 | */ | ||
| 458 | wait_queue_head_t tx_waitq; | 533 | wait_queue_head_t tx_waitq; |
| 534 | /** | ||
| 535 | * @work: Probe work. | ||
| 536 | */ | ||
| 459 | struct work_struct work; | 537 | struct work_struct work; |
| 460 | 538 | /** | |
| 539 | * @tx_work: Sideband transmit worker. This can nest within the main | ||
| 540 | * @work worker for each transaction @work launches. | ||
| 541 | */ | ||
| 461 | struct work_struct tx_work; | 542 | struct work_struct tx_work; |
| 462 | 543 | ||
| 544 | /** | ||
| 545 | * @destroy_connector_list: List of to be destroyed connectors. | ||
| 546 | */ | ||
| 463 | struct list_head destroy_connector_list; | 547 | struct list_head destroy_connector_list; |
| 548 | /** | ||
| 549 | * @destroy_connector_lock: Protects @connector_list. | ||
| 550 | */ | ||
| 464 | struct mutex destroy_connector_lock; | 551 | struct mutex destroy_connector_lock; |
| 552 | /** | ||
| 553 | * @destroy_connector_work: Work item to destroy connectors. Needed to | ||
| 554 | * avoid locking inversion. | ||
| 555 | */ | ||
| 465 | struct work_struct destroy_connector_work; | 556 | struct work_struct destroy_connector_work; |
| 466 | }; | 557 | }; |
| 467 | 558 | ||
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h new file mode 100644 index 000000000000..2401b14d301f --- /dev/null +++ b/include/drm/drm_irq.h | |||
| @@ -0,0 +1,183 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 Intel Corp. | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice (including the next | ||
| 12 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 13 | * Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 21 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef _DRM_IRQ_H_ | ||
| 25 | #define _DRM_IRQ_H_ | ||
| 26 | |||
| 27 | #include <linux/seqlock.h> | ||
| 28 | |||
| 29 | /** | ||
| 30 | * struct drm_pending_vblank_event - pending vblank event tracking | ||
| 31 | */ | ||
| 32 | struct drm_pending_vblank_event { | ||
| 33 | /** | ||
| 34 | * @base: Base structure for tracking pending DRM events. | ||
| 35 | */ | ||
| 36 | struct drm_pending_event base; | ||
| 37 | /** | ||
| 38 | * @pipe: drm_crtc_index() of the &drm_crtc this event is for. | ||
| 39 | */ | ||
| 40 | unsigned int pipe; | ||
| 41 | /** | ||
| 42 | * @event: Actual event which will be sent to userspace. | ||
| 43 | */ | ||
| 44 | struct drm_event_vblank event; | ||
| 45 | }; | ||
| 46 | |||
| 47 | /** | ||
| 48 | * struct drm_vblank_crtc - vblank tracking for a CRTC | ||
| 49 | * | ||
| 50 | * This structure tracks the vblank state for one CRTC. | ||
| 51 | * | ||
| 52 | * Note that for historical reasons - the vblank handling code is still shared | ||
| 53 | * with legacy/non-kms drivers - this is a free-standing structure not directly | ||
| 54 | * connected to struct &drm_crtc. But all public interface functions are taking | ||
| 55 | * a struct &drm_crtc to hide this implementation detail. | ||
| 56 | */ | ||
| 57 | struct drm_vblank_crtc { | ||
| 58 | /** | ||
| 59 | * @dev: Pointer to the &drm_device. | ||
| 60 | */ | ||
| 61 | struct drm_device *dev; | ||
| 62 | /** | ||
| 63 | * @queue: Wait queue for vblank waiters. | ||
| 64 | */ | ||
| 65 | wait_queue_head_t queue; /**< VBLANK wait queue */ | ||
| 66 | /** | ||
| 67 | * @disable_timer: Disable timer for the delayed vblank disabling | ||
| 68 | * hysteresis logic. Vblank disabling is controlled through the | ||
| 69 | * drm_vblank_offdelay module option and the setting of the | ||
| 70 | * max_vblank_count value in the &drm_device structure. | ||
| 71 | */ | ||
| 72 | struct timer_list disable_timer; | ||
| 73 | |||
| 74 | /** | ||
| 75 | * @seqlock: Protect vblank count and time. | ||
| 76 | */ | ||
| 77 | seqlock_t seqlock; /* protects vblank count and time */ | ||
| 78 | |||
| 79 | /** | ||
| 80 | * @count: Current software vblank counter. | ||
| 81 | */ | ||
| 82 | u32 count; | ||
| 83 | /** | ||
| 84 | * @time: Vblank timestamp corresponding to @count. | ||
| 85 | */ | ||
| 86 | struct timeval time; | ||
| 87 | |||
| 88 | /** | ||
| 89 | * @refcount: Number of users/waiters of the vblank interrupt. Only when | ||
| 90 | * this refcount reaches 0 can the hardware interrupt be disabled using | ||
| 91 | * @disable_timer. | ||
| 92 | */ | ||
| 93 | atomic_t refcount; /* number of users of vblank interruptsper crtc */ | ||
| 94 | /** | ||
| 95 | * @last: Protected by dev->vbl_lock, used for wraparound handling. | ||
| 96 | */ | ||
| 97 | u32 last; | ||
| 98 | /** | ||
| 99 | * @inmodeset: Tracks whether the vblank is disabled due to a modeset. | ||
| 100 | * For legacy driver bit 2 additionally tracks whether an additional | ||
| 101 | * temporary vblank reference has been acquired to paper over the | ||
| 102 | * hardware counter resetting/jumping. KMS drivers should instead just | ||
| 103 | * call drm_crtc_vblank_off() and drm_crtc_vblank_on(), which explicitly | ||
| 104 | * save and restore the vblank count. | ||
| 105 | */ | ||
| 106 | unsigned int inmodeset; /* Display driver is setting mode */ | ||
| 107 | /** | ||
| 108 | * @pipe: drm_crtc_index() of the &drm_crtc corresponding to this | ||
| 109 | * structure. | ||
| 110 | */ | ||
| 111 | unsigned int pipe; | ||
| 112 | /** | ||
| 113 | * @framedur_ns: Frame/Field duration in ns, used by | ||
| 114 | * drm_calc_vbltimestamp_from_scanoutpos() and computed by | ||
| 115 | * drm_calc_timestamping_constants(). | ||
| 116 | */ | ||
| 117 | int framedur_ns; | ||
| 118 | /** | ||
| 119 | * @linedur_ns: Line duration in ns, used by | ||
| 120 | * drm_calc_vbltimestamp_from_scanoutpos() and computed by | ||
| 121 | * drm_calc_timestamping_constants(). | ||
| 122 | */ | ||
| 123 | int linedur_ns; | ||
| 124 | /** | ||
| 125 | * @enabled: Tracks the enabling state of the corresponding &drm_crtc to | ||
| 126 | * avoid double-disabling and hence corrupting saved state. Needed by | ||
| 127 | * drivers not using atomic KMS, since those might go through their CRTC | ||
| 128 | * disabling functions multiple times. | ||
| 129 | */ | ||
| 130 | bool enabled; | ||
| 131 | }; | ||
| 132 | |||
| 133 | extern int drm_irq_install(struct drm_device *dev, int irq); | ||
| 134 | extern int drm_irq_uninstall(struct drm_device *dev); | ||
| 135 | |||
| 136 | extern int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); | ||
| 137 | extern int drm_wait_vblank(struct drm_device *dev, void *data, | ||
| 138 | struct drm_file *filp); | ||
| 139 | extern u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe); | ||
| 140 | extern u32 drm_crtc_vblank_count(struct drm_crtc *crtc); | ||
| 141 | extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, | ||
| 142 | struct timeval *vblanktime); | ||
| 143 | extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc, | ||
| 144 | struct drm_pending_vblank_event *e); | ||
| 145 | extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, | ||
| 146 | struct drm_pending_vblank_event *e); | ||
| 147 | extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); | ||
| 148 | extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc); | ||
| 149 | extern int drm_crtc_vblank_get(struct drm_crtc *crtc); | ||
| 150 | extern void drm_crtc_vblank_put(struct drm_crtc *crtc); | ||
| 151 | extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); | ||
| 152 | extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); | ||
| 153 | extern void drm_vblank_off(struct drm_device *dev, unsigned int pipe); | ||
| 154 | extern void drm_vblank_on(struct drm_device *dev, unsigned int pipe); | ||
| 155 | extern void drm_crtc_vblank_off(struct drm_crtc *crtc); | ||
| 156 | extern void drm_crtc_vblank_reset(struct drm_crtc *crtc); | ||
| 157 | extern void drm_crtc_vblank_on(struct drm_crtc *crtc); | ||
| 158 | extern void drm_vblank_cleanup(struct drm_device *dev); | ||
| 159 | extern u32 drm_accurate_vblank_count(struct drm_crtc *crtc); | ||
| 160 | extern u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe); | ||
| 161 | |||
| 162 | extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, | ||
| 163 | unsigned int pipe, int *max_error, | ||
| 164 | struct timeval *vblank_time, | ||
| 165 | unsigned flags, | ||
| 166 | const struct drm_display_mode *mode); | ||
| 167 | extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, | ||
| 168 | const struct drm_display_mode *mode); | ||
| 169 | |||
| 170 | /** | ||
| 171 | * drm_crtc_vblank_waitqueue - get vblank waitqueue for the CRTC | ||
| 172 | * @crtc: which CRTC's vblank waitqueue to retrieve | ||
| 173 | * | ||
| 174 | * This function returns a pointer to the vblank waitqueue for the CRTC. | ||
| 175 | * Drivers can use this to implement vblank waits using wait_event() and related | ||
| 176 | * functions. | ||
| 177 | */ | ||
| 178 | static inline wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc) | ||
| 179 | { | ||
| 180 | return &crtc->dev->vblank[drm_crtc_index(crtc)].queue; | ||
| 181 | } | ||
| 182 | |||
| 183 | #endif | ||
diff --git a/include/uapi/drm/vgem_drm.h b/include/uapi/drm/vgem_drm.h new file mode 100644 index 000000000000..bf66f5db6da8 --- /dev/null +++ b/include/uapi/drm/vgem_drm.h | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 Intel Corporation | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 | * copy of this software and associated documentation files (the | ||
| 7 | * "Software"), to deal in the Software without restriction, including | ||
| 8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
| 9 | * distribute, sub license, and/or sell copies of the Software, and to | ||
| 10 | * permit persons to whom the Software is furnished to do so, subject to | ||
| 11 | * the following conditions: | ||
| 12 | * | ||
| 13 | * The above copyright notice and this permission notice (including the | ||
| 14 | * next paragraph) shall be included in all copies or substantial portions | ||
| 15 | * of the Software. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | ||
| 21 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
| 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
| 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef _UAPI_VGEM_DRM_H_ | ||
| 28 | #define _UAPI_VGEM_DRM_H_ | ||
| 29 | |||
| 30 | #include "drm.h" | ||
| 31 | |||
| 32 | #if defined(__cplusplus) | ||
| 33 | extern "C" { | ||
| 34 | #endif | ||
| 35 | |||
| 36 | /* Please note that modifications to all structs defined here are | ||
| 37 | * subject to backwards-compatibility constraints. | ||
| 38 | */ | ||
| 39 | #define DRM_VGEM_FENCE_ATTACH 0x1 | ||
| 40 | #define DRM_VGEM_FENCE_SIGNAL 0x2 | ||
| 41 | |||
| 42 | #define DRM_IOCTL_VGEM_FENCE_ATTACH DRM_IOWR( DRM_COMMAND_BASE + DRM_VGEM_FENCE_ATTACH, struct drm_vgem_fence_attach) | ||
| 43 | #define DRM_IOCTL_VGEM_FENCE_SIGNAL DRM_IOW( DRM_COMMAND_BASE + DRM_VGEM_FENCE_SIGNAL, struct drm_vgem_fence_signal) | ||
| 44 | |||
| 45 | struct drm_vgem_fence_attach { | ||
| 46 | __u32 handle; | ||
| 47 | __u32 flags; | ||
| 48 | #define VGEM_FENCE_WRITE 0x1 | ||
| 49 | __u32 out_fence; | ||
| 50 | __u32 pad; | ||
| 51 | }; | ||
| 52 | |||
| 53 | struct drm_vgem_fence_signal { | ||
| 54 | __u32 fence; | ||
| 55 | __u32 flags; | ||
| 56 | }; | ||
| 57 | |||
| 58 | #if defined(__cplusplus) | ||
| 59 | } | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #endif /* _UAPI_VGEM_DRM_H_ */ | ||
