diff options
author | Dave Airlie <airlied@redhat.com> | 2017-08-17 07:33:41 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-08-17 07:33:41 +1000 |
commit | 3154b133711f70bb50f513773947a8a647d24310 (patch) | |
tree | be1284614bc52cec292ebc150d9983ca08af34cc | |
parent | efa479352fc780b305fa186cafb5f416fdf2b2cb (diff) | |
parent | d956e1293b9b43f3a9a508162cdbaa96cf02e6e0 (diff) | |
download | op-kernel-dev-3154b133711f70bb50f513773947a8a647d24310.zip op-kernel-dev-3154b133711f70bb50f513773947a8a647d24310.tar.gz |
Merge tag 'drm-misc-next-2017-08-16' of git://anongit.freedesktop.org/git/drm-misc into drm-next
UAPI Changes:
- vc4: Allow userspace to dictate rendering order in submit_cl ioctl (Eric)
Cross-subsystem Changes:
- vboxvideo: One of Cihangir's patches applies to vboxvideo which is maintained
in staging
Core Changes:
- atomic_legacy_backoff is officially killed (Daniel)
- Extract drm_device.h (Daniel)
- Unregister drm device on unplug (Daniel)
- Rename deprecated drm_*_(un)?reference functions to drm_*_{get|put} (Cihangir)
Driver Changes:
- vc4: Error/destroy path cleanups, log level demotion, edid leak (Eric)
- various: Make various drm_*_funcs structs const (Bhumika)
- tinydrm: add support for LEGO MINDSTORMS EV3 LCD (David)
- various: Second half of .dumb_{map_offset|destroy} defaults set (Noralf)
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Eric Anholt <eric@anholt.net>
Cc: Bhumika Goyal <bhumirks@gmail.com>
Cc: Cihangir Akturk <cakturk@gmail.com>
Cc: David Lechner <david@lechnology.com>
Cc: Noralf Trønnes <noralf@tronnes.org>
* tag 'drm-misc-next-2017-08-16' of git://anongit.freedesktop.org/git/drm-misc: (50 commits)
drm/gem-cma-helper: Remove drm_gem_cma_dumb_map_offset()
drm/virtio: Use the drm_driver.dumb_destroy default
drm/bochs: Use the drm_driver.dumb_destroy default
drm/mgag200: Use the drm_driver.dumb_destroy default
drm/exynos: Use .dumb_map_offset and .dumb_destroy defaults
drm/msm: Use the drm_driver.dumb_destroy default
drm/ast: Use the drm_driver.dumb_destroy default
drm/qxl: Use the drm_driver.dumb_destroy default
drm/udl: Use the drm_driver.dumb_destroy default
drm/cirrus: Use the drm_driver.dumb_destroy default
drm/tegra: Use .dumb_map_offset and .dumb_destroy defaults
drm/gma500: Use .dumb_map_offset and .dumb_destroy defaults
drm/mxsfb: Use .dumb_map_offset and .dumb_destroy defaults
drm/meson: Use .dumb_map_offset and .dumb_destroy defaults
drm/kirin: Use .dumb_map_offset and .dumb_destroy defaults
drm/vc4: Continue the switch to drm_*_put() helpers
drm/vc4: Fix leak of HDMI EDID
dma-buf: fix reservation_object_wait_timeout_rcu to wait correctly v2
dma-buf: add reservation_object_copy_fences (v2)
drm/tinydrm: add support for LEGO MINDSTORMS EV3 LCD
...
88 files changed, 1059 insertions, 628 deletions
diff --git a/Documentation/devicetree/bindings/display/sitronix,st7586.txt b/Documentation/devicetree/bindings/display/sitronix,st7586.txt new file mode 100644 index 0000000..1d0dad1 --- /dev/null +++ b/Documentation/devicetree/bindings/display/sitronix,st7586.txt @@ -0,0 +1,22 @@ +Sitronix ST7586 display panel + +Required properties: +- compatible: "lego,ev3-lcd". +- a0-gpios: The A0 signal (since this binding is for serial mode, this is + the pin labeled D1 on the controller, not the pin labeled A0) +- reset-gpios: Reset pin + +The node for this driver must be a child node of a SPI controller, hence +all mandatory properties described in ../spi/spi-bus.txt must be specified. + +Optional properties: +- rotation: panel rotation in degrees counter clockwise (0,90,180,270) + +Example: + display@0{ + compatible = "lego,ev3-lcd"; + reg = <0>; + spi-max-frequency = <10000000>; + a0-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index a6c2306..fdba5f6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4380,6 +4380,12 @@ S: Orphan / Obsolete F: drivers/gpu/drm/sis/ F: include/uapi/drm/sis_drm.h +DRM DRIVER FOR SITRONIX ST7586 PANELS +M: David Lechner <david@lechnology.com> +S: Maintained +F: drivers/gpu/drm/tinydrm/st7586.c +F: Documentation/devicetree/bindings/display/st7586.txt + DRM DRIVER FOR TDFX VIDEO CARDS S: Orphan / Obsolete F: drivers/gpu/drm/tdfx/ diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c index 393817e..dec3a81 100644 --- a/drivers/dma-buf/reservation.c +++ b/drivers/dma-buf/reservation.c @@ -195,8 +195,7 @@ done: if (old) kfree_rcu(old, rcu); - if (old_fence) - dma_fence_put(old_fence); + dma_fence_put(old_fence); } /** @@ -258,12 +257,71 @@ void reservation_object_add_excl_fence(struct reservation_object *obj, dma_fence_put(rcu_dereference_protected(old->shared[i], reservation_object_held(obj))); - if (old_fence) - dma_fence_put(old_fence); + dma_fence_put(old_fence); } EXPORT_SYMBOL(reservation_object_add_excl_fence); /** +* reservation_object_copy_fences - Copy all fences from src to dst. +* @dst: the destination reservation object +* @src: the source reservation object +* +* Copy all fences from src to dst. Both src->lock as well as dst-lock must be +* held. +*/ +int reservation_object_copy_fences(struct reservation_object *dst, + struct reservation_object *src) +{ + struct reservation_object_list *src_list, *dst_list; + struct dma_fence *old, *new; + size_t size; + unsigned i; + + src_list = reservation_object_get_list(src); + + if (src_list) { + size = offsetof(typeof(*src_list), + shared[src_list->shared_count]); + dst_list = kmalloc(size, GFP_KERNEL); + if (!dst_list) + return -ENOMEM; + + dst_list->shared_count = src_list->shared_count; + dst_list->shared_max = src_list->shared_count; + for (i = 0; i < src_list->shared_count; ++i) + dst_list->shared[i] = + dma_fence_get(src_list->shared[i]); + } else { + dst_list = NULL; + } + + kfree(dst->staged); + dst->staged = NULL; + + src_list = reservation_object_get_list(dst); + + old = reservation_object_get_excl(dst); + new = reservation_object_get_excl(src); + + dma_fence_get(new); + + preempt_disable(); + write_seqcount_begin(&dst->seq); + /* write_seqcount_begin provides the necessary memory barrier */ + RCU_INIT_POINTER(dst->fence_excl, new); + RCU_INIT_POINTER(dst->fence, dst_list); + write_seqcount_end(&dst->seq); + preempt_enable(); + + if (src_list) + kfree_rcu(src_list, rcu); + dma_fence_put(old); + + return 0; +} +EXPORT_SYMBOL(reservation_object_copy_fences); + +/** * reservation_object_get_fences_rcu - Get an object's shared and exclusive * fences without update side lock held * @obj: the reservation object @@ -373,12 +431,25 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj, long ret = timeout ? timeout : 1; retry: - fence = NULL; shared_count = 0; seq = read_seqcount_begin(&obj->seq); rcu_read_lock(); - if (wait_all) { + fence = rcu_dereference(obj->fence_excl); + if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { + if (!dma_fence_get_rcu(fence)) + goto unlock_retry; + + if (dma_fence_is_signaled(fence)) { + dma_fence_put(fence); + fence = NULL; + } + + } else { + fence = NULL; + } + + if (!fence && wait_all) { struct reservation_object_list *fobj = rcu_dereference(obj->fence); @@ -405,22 +476,6 @@ retry: } } - if (!shared_count) { - struct dma_fence *fence_excl = rcu_dereference(obj->fence_excl); - - if (fence_excl && - !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &fence_excl->flags)) { - if (!dma_fence_get_rcu(fence_excl)) - goto unlock_retry; - - if (dma_fence_is_signaled(fence_excl)) - dma_fence_put(fence_excl); - else - fence = fence_excl; - } - } - rcu_read_unlock(); if (fence) { if (read_seqcount_retry(&obj->seq, seq)) { diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index e3c13aa..289eda5 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -31,7 +31,7 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev) drm_fbdev_cma_hotplug_event(arcpgu->fbdev); } -static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { +static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { .fb_create = drm_fb_cma_create, .output_poll_changed = arcpgu_fb_output_poll_changed, .atomic_check = drm_atomic_helper_check, diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 3022b39..69dab82 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -209,7 +209,6 @@ static struct drm_driver driver = { .gem_free_object_unlocked = ast_gem_free_object, .dumb_create = ast_dumb_create, .dumb_map_offset = ast_dumb_mmap_offset, - .dumb_destroy = drm_gem_dumb_destroy, }; diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index 9052ebe..0cd827e 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c @@ -266,7 +266,7 @@ static void ast_fbdev_destroy(struct drm_device *dev, drm_fb_helper_unregister_fbi(&afbdev->helper); if (afb->obj) { - drm_gem_object_unreference_unlocked(afb->obj); + drm_gem_object_put_unlocked(afb->obj); afb->obj = NULL; } drm_fb_helper_fini(&afbdev->helper); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 9a44cde..dac3558 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -387,7 +387,7 @@ static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb); - drm_gem_object_unreference_unlocked(ast_fb->obj); + drm_gem_object_put_unlocked(ast_fb->obj); drm_framebuffer_cleanup(fb); kfree(ast_fb); } @@ -429,13 +429,13 @@ ast_user_framebuffer_create(struct drm_device *dev, ast_fb = kzalloc(sizeof(*ast_fb), GFP_KERNEL); if (!ast_fb) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ERR_PTR(-ENOMEM); } ret = ast_framebuffer_init(dev, ast_fb, mode_cmd, obj); if (ret) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); kfree(ast_fb); return ERR_PTR(ret); } @@ -628,7 +628,7 @@ int ast_dumb_create(struct drm_file *file, return ret; ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); if (ret) return ret; @@ -676,7 +676,7 @@ ast_dumb_mmap_offset(struct drm_file *file, bo = gem_to_ast_bo(obj); *offset = ast_bo_mmap_offset(bo); - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return 0; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 4324522..6f3849e 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -950,7 +950,7 @@ static void ast_cursor_fini(struct drm_device *dev) { struct ast_private *ast = dev->dev_private; ttm_bo_kunmap(&ast->cache_kmap); - drm_gem_object_unreference_unlocked(ast->cursor_cache); + drm_gem_object_put_unlocked(ast->cursor_cache); } int ast_mode_init(struct drm_device *dev) @@ -1215,10 +1215,10 @@ static int ast_cursor_set(struct drm_crtc *crtc, ast_show_cursor(crtc); - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return 0; fail: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ret; } diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index a1d2884..7b203184 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -93,7 +93,6 @@ static struct drm_driver bochs_driver = { .gem_free_object_unlocked = bochs_gem_free_object, .dumb_create = bochs_dumb_create, .dumb_map_offset = bochs_dumb_mmap_offset, - .dumb_destroy = drm_gem_dumb_destroy, }; /* ---------------------------------------------------------------------- */ diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 682c090..b2431ae 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -785,7 +785,7 @@ adv7511_connector_detect(struct drm_connector *connector, bool force) return adv7511_detect(adv, connector); } -static struct drm_connector_funcs adv7511_connector_funcs = { +static const struct drm_connector_funcs adv7511_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .detect = adv7511_connector_detect, .destroy = drm_connector_cleanup, @@ -856,7 +856,7 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge) return ret; } -static struct drm_bridge_funcs adv7511_bridge_funcs = { +static const struct drm_bridge_funcs adv7511_bridge_funcs = { .enable = adv7511_bridge_enable, .disable = adv7511_bridge_disable, .mode_set = adv7511_bridge_mode_set, diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c index 8f2d137..cf3f0ca 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c @@ -517,7 +517,7 @@ static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream) return bytes_to_frames(runtime, dw->buf_offset); } -static struct snd_pcm_ops snd_dw_hdmi_ops = { +static const struct snd_pcm_ops snd_dw_hdmi_ops = { .open = dw_hdmi_open, .close = dw_hdmi_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 36f5ccb..63c7a01 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -811,7 +811,7 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge) return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge); } -static struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { +static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { .mode_set = dw_mipi_dsi_bridge_mode_set, .enable = dw_mipi_dsi_bridge_enable, .post_disable = dw_mipi_dsi_bridge_post_disable, diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 910c300..69c4e35 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -142,7 +142,6 @@ static struct drm_driver driver = { .gem_free_object_unlocked = cirrus_gem_free_object, .dumb_create = cirrus_dumb_create, .dumb_map_offset = cirrus_dumb_mmap_offset, - .dumb_destroy = drm_gem_dumb_destroy, }; static const struct dev_pm_ops cirrus_pm_ops = { diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c index 0f6815f..32fbfba 100644 --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c @@ -251,7 +251,7 @@ static int cirrus_fbdev_destroy(struct drm_device *dev, drm_fb_helper_unregister_fbi(&gfbdev->helper); if (gfb->obj) { - drm_gem_object_unreference_unlocked(gfb->obj); + drm_gem_object_put_unlocked(gfb->obj); gfb->obj = NULL; } diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c index e7fc95f..b5f5285 100644 --- a/drivers/gpu/drm/cirrus/cirrus_main.c +++ b/drivers/gpu/drm/cirrus/cirrus_main.c @@ -18,7 +18,7 @@ static void cirrus_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct cirrus_framebuffer *cirrus_fb = to_cirrus_framebuffer(fb); - drm_gem_object_unreference_unlocked(cirrus_fb->obj); + drm_gem_object_put_unlocked(cirrus_fb->obj); drm_framebuffer_cleanup(fb); kfree(fb); } @@ -67,13 +67,13 @@ cirrus_user_framebuffer_create(struct drm_device *dev, cirrus_fb = kzalloc(sizeof(*cirrus_fb), GFP_KERNEL); if (!cirrus_fb) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ERR_PTR(-ENOMEM); } ret = cirrus_framebuffer_init(dev, cirrus_fb, mode_cmd, obj); if (ret) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); kfree(cirrus_fb); return ERR_PTR(ret); } @@ -261,7 +261,7 @@ int cirrus_dumb_create(struct drm_file *file, return ret; ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); if (ret) return ret; @@ -310,7 +310,7 @@ cirrus_dumb_mmap_offset(struct drm_file *file, bo = gem_to_cirrus_bo(obj); *offset = cirrus_bo_mmap_offset(bo); - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return 0; } diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 2ed2d91..be38ac7 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -291,7 +291,7 @@ struct drm_minor *drm_minor_acquire(unsigned int minor_id) if (!minor) { return ERR_PTR(-ENODEV); - } else if (drm_device_is_unplugged(minor->dev)) { + } else if (drm_dev_is_unplugged(minor->dev)) { drm_dev_unref(minor->dev); return ERR_PTR(-ENODEV); } @@ -364,26 +364,32 @@ void drm_put_dev(struct drm_device *dev) } EXPORT_SYMBOL(drm_put_dev); -void drm_unplug_dev(struct drm_device *dev) +static void drm_device_set_unplugged(struct drm_device *dev) { - /* for a USB device */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_modeset_unregister_all(dev); + smp_wmb(); + atomic_set(&dev->unplugged, 1); +} - drm_minor_unregister(dev, DRM_MINOR_PRIMARY); - drm_minor_unregister(dev, DRM_MINOR_RENDER); - drm_minor_unregister(dev, DRM_MINOR_CONTROL); +/** + * drm_dev_unplug - unplug a DRM device + * @dev: DRM device + * + * This unplugs a hotpluggable DRM device, which makes it inaccessible to + * userspace operations. Entry-points can use drm_dev_is_unplugged(). This + * essentially unregisters the device like drm_dev_unregister(), but can be + * called while there are still open users of @dev. + */ +void drm_dev_unplug(struct drm_device *dev) +{ + drm_dev_unregister(dev); mutex_lock(&drm_global_mutex); - drm_device_set_unplugged(dev); - - if (dev->open_count == 0) { - drm_put_dev(dev); - } + if (dev->open_count == 0) + drm_dev_unref(dev); mutex_unlock(&drm_global_mutex); } -EXPORT_SYMBOL(drm_unplug_dev); +EXPORT_SYMBOL(drm_dev_unplug); /* * DRM internal mount @@ -835,6 +841,9 @@ EXPORT_SYMBOL(drm_dev_register); * drm_dev_register() but does not deallocate the device. The caller must call * drm_dev_unref() to drop their final reference. * + * A special form of unregistering for hotpluggable devices is drm_dev_unplug(), + * which can be called while there are still open users of @dev. + * * This should be called first in the device teardown code to make sure * userspace can't access the device instance any more. */ @@ -842,7 +851,8 @@ void drm_dev_unregister(struct drm_device *dev) { struct drm_map_list *r_list, *list_temp; - drm_lastclose(dev); + if (drm_core_check_feature(dev, DRIVER_LEGACY)) + drm_lastclose(dev); dev->registered = false; diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 59b75a9..b3c6e99 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -436,7 +436,7 @@ int drm_release(struct inode *inode, struct file *filp) if (!--dev->open_count) { drm_lastclose(dev); - if (drm_device_is_unplugged(dev)) + if (drm_dev_is_unplugged(dev)) drm_put_dev(dev); } mutex_unlock(&drm_global_mutex); diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index a8d396b..ad4e9cf 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -1001,7 +1001,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) struct drm_vma_offset_node *node; int ret; - if (drm_device_is_unplugged(dev)) + if (drm_dev_is_unplugged(dev)) return -ENODEV; drm_vma_offset_lock_lookup(dev->vma_offset_manager); diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 275ab87..373e33f 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -264,41 +264,6 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, } EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create); -/** - * drm_gem_cma_dumb_map_offset - return the fake mmap offset for a CMA GEM - * object - * @file_priv: DRM file-private structure containing the GEM object - * @drm: DRM device - * @handle: GEM object handle - * @offset: return location for the fake mmap offset - * - * This function look up an object by its handle and returns the fake mmap - * offset associated with it. Drivers using the CMA helpers should set this - * as their &drm_driver.dumb_map_offset callback. - * - * Returns: - * 0 on success or a negative error code on failure. - */ -int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *drm, u32 handle, - u64 *offset) -{ - struct drm_gem_object *gem_obj; - - gem_obj = drm_gem_object_lookup(file_priv, handle); - if (!gem_obj) { - dev_err(drm->dev, "failed to lookup GEM object\n"); - return -EINVAL; - } - - *offset = drm_vma_node_offset_addr(&gem_obj->vma_node); - - drm_gem_object_put_unlocked(gem_obj); - - return 0; -} -EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_map_offset); - const struct vm_operations_struct drm_gem_cma_vm_ops = { .open = drm_gem_vm_open, .close = drm_gem_vm_close, @@ -390,7 +355,7 @@ unsigned long drm_gem_cma_get_unmapped_area(struct file *filp, struct drm_device *dev = priv->minor->dev; struct drm_vma_offset_node *node; - if (drm_device_is_unplugged(dev)) + if (drm_dev_is_unplugged(dev)) return -ENODEV; drm_vma_offset_lock_lookup(dev->vma_offset_manager); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 8bfeb32..d920b21 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -716,7 +716,7 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata, struct drm_device *dev = file_priv->minor->dev; int retcode; - if (drm_device_is_unplugged(dev)) + if (drm_dev_is_unplugged(dev)) return -ENODEV; retcode = drm_ioctl_permit(flags, file_priv); @@ -765,7 +765,7 @@ long drm_ioctl(struct file *filp, dev = file_priv->minor->dev; - if (drm_device_is_unplugged(dev)) + if (drm_dev_is_unplugged(dev)) return -ENODEV; is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 5c14bee..85ab1ee 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -126,7 +126,7 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane plane->format_types[j], plane->modifiers[i])) { - mod->formats |= 1 << j; + mod->formats |= 1ULL << j; } } diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 1170b32..13a59ed 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -631,7 +631,7 @@ int drm_legacy_mmap(struct file *filp, struct vm_area_struct *vma) struct drm_device *dev = priv->minor->dev; int ret; - if (drm_device_is_unplugged(dev)) + if (drm_dev_is_unplugged(dev)) return -ENODEV; mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index facc841..b1f7299 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -145,8 +145,6 @@ static struct drm_driver exynos_drm_driver = { .gem_free_object_unlocked = exynos_drm_gem_free_object, .gem_vm_ops = &exynos_drm_gem_vm_ops, .dumb_create = exynos_drm_gem_dumb_create, - .dumb_map_offset = exynos_drm_gem_dumb_map_offset, - .dumb_destroy = drm_gem_dumb_destroy, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = drm_gem_prime_export, diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index c23479b..077de01 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -286,8 +286,8 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data, { struct drm_exynos_gem_map *args = data; - return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle, - &args->offset); + return drm_gem_dumb_map_offset(file_priv, dev, args->handle, + &args->offset); } dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev, @@ -422,32 +422,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, return 0; } -int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle, - uint64_t *offset) -{ - struct drm_gem_object *obj; - int ret = 0; - - /* - * get offset of memory allocated for drm framebuffer. - * - this callback would be called by user application - * with DRM_IOCTL_MODE_MAP_DUMB command. - */ - - obj = drm_gem_object_lookup(file_priv, handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return -EINVAL; - } - - *offset = drm_vma_node_offset_addr(&obj->vma_node); - DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset); - - drm_gem_object_unreference_unlocked(obj); - return ret; -} - int exynos_drm_gem_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 8545725..e86d1a9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -110,11 +110,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); -/* map memory region for drm framebuffer to user space. */ -int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle, - uint64_t *offset); - /* page fault handler and mmap fault address(virtual) to physical memory. */ int exynos_drm_gem_fault(struct vm_fault *vmf); diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index 7da061a..1312397 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c @@ -48,36 +48,6 @@ int psb_gem_get_aperture(struct drm_device *dev, void *data, } /** - * psb_gem_dumb_map_gtt - buffer mapping for dumb interface - * @file: our drm client file - * @dev: drm device - * @handle: GEM handle to the object (from dumb_create) - * - * Do the necessary setup to allow the mapping of the frame buffer - * into user memory. We don't have to do much here at the moment. - */ -int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset) -{ - int ret = 0; - struct drm_gem_object *obj; - - /* GEM does all our handle to object mapping */ - obj = drm_gem_object_lookup(file, handle); - if (obj == NULL) - return -ENOENT; - - /* Make it mmapable */ - ret = drm_gem_create_mmap_offset(obj); - if (ret) - goto out; - *offset = drm_vma_node_offset_addr(&obj->vma_node); -out: - drm_gem_object_unreference_unlocked(obj); - return ret; -} - -/** * psb_gem_create - create a mappable object * @file: the DRM file of the client * @dev: our device diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 747c06b..37a3be7 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -494,8 +494,6 @@ static struct drm_driver driver = { .gem_vm_ops = &psb_gem_vm_ops, .dumb_create = psb_gem_dumb_create, - .dumb_map_offset = psb_gem_dumb_map_gtt, - .dumb_destroy = drm_gem_dumb_destroy, .ioctls = psb_ioctls, .fops = &psb_gem_fops, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 8366708..821497d 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -750,8 +750,6 @@ extern int psb_gem_get_aperture(struct drm_device *dev, void *data, struct drm_file *file); extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); -extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset); extern int psb_gem_fault(struct vm_fault *vmf); /* psb_device.c */ diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c index 9740eed..b92595c 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c @@ -157,7 +157,7 @@ out_unpin_bo: out_unreserve_ttm_bo: ttm_bo_unreserve(&bo->bo); out_unref_gem: - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); return ret; } @@ -172,7 +172,7 @@ static void hibmc_fbdev_destroy(struct hibmc_fbdev *fbdev) drm_fb_helper_fini(fbh); if (gfb) - drm_framebuffer_unreference(&gfb->fb); + drm_framebuffer_put(&gfb->fb); } static const struct drm_fb_helper_funcs hibmc_fbdev_helper_funcs = { diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c index ac457c7..3518167 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c @@ -444,7 +444,7 @@ int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, } ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); if (ret) { DRM_ERROR("failed to unreference GEM object: %d\n", ret); return ret; @@ -479,7 +479,7 @@ int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, bo = gem_to_hibmc_bo(obj); *offset = hibmc_bo_mmap_offset(bo); - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return 0; } @@ -487,7 +487,7 @@ static void hibmc_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct hibmc_framebuffer *hibmc_fb = to_hibmc_framebuffer(fb); - drm_gem_object_unreference_unlocked(hibmc_fb->obj); + drm_gem_object_put_unlocked(hibmc_fb->obj); drm_framebuffer_cleanup(fb); kfree(hibmc_fb); } @@ -543,7 +543,7 @@ hibmc_user_framebuffer_create(struct drm_device *dev, hibmc_fb = hibmc_framebuffer_init(dev, mode_cmd, obj); if (IS_ERR(hibmc_fb)) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ERR_PTR((long)hibmc_fb); } return &hibmc_fb->fb; diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 79fcce7..e27352c 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -157,8 +157,6 @@ static struct drm_driver kirin_drm_driver = { .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = kirin_gem_cma_dumb_create, - .dumb_map_offset = drm_gem_cma_dumb_map_offset, - .dumb_destroy = drm_gem_dumb_destroy, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c index d4246c9..0d8d506 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c @@ -58,7 +58,7 @@ static void mtk_drm_fb_destroy(struct drm_framebuffer *fb) drm_framebuffer_cleanup(fb); - drm_gem_object_unreference_unlocked(mtk_fb->gem_obj); + drm_gem_object_put_unlocked(mtk_fb->gem_obj); kfree(mtk_fb); } @@ -160,6 +160,6 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev, return &mtk_fb->base; unreference: - drm_gem_object_unreference_unlocked(gem); + drm_gem_object_put_unlocked(gem); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 8ec963f..f595ac8 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -122,7 +122,7 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, goto err_handle_create; /* drop reference from allocate - handle holds it now. */ - drm_gem_object_unreference_unlocked(&mtk_gem->base); + drm_gem_object_put_unlocked(&mtk_gem->base); return 0; diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 5375e6d..7742c7d 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -116,8 +116,6 @@ static struct drm_driver meson_driver = { /* GEM Ops */ .dumb_create = drm_gem_cma_dumb_create, - .dumb_destroy = drm_gem_dumb_destroy, - .dumb_map_offset = drm_gem_cma_dumb_map_offset, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index 2ac3fcb..968e203 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -248,7 +248,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, out_unreserve1: mgag200_bo_unreserve(pixels_2); out_unref: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ret; } diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 4189160..74cdde2 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -102,7 +102,6 @@ static struct drm_driver driver = { .gem_free_object_unlocked = mgag200_gem_free_object, .dumb_create = mgag200_dumb_create, .dumb_map_offset = mgag200_dumb_mmap_offset, - .dumb_destroy = drm_gem_dumb_destroy, }; static struct pci_driver mgag200_pci_driver = { diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c index 9d914ca..30726c9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_fb.c +++ b/drivers/gpu/drm/mgag200/mgag200_fb.c @@ -232,7 +232,7 @@ static int mgag200fb_create(struct drm_fb_helper *helper, err_alloc_fbi: vfree(sysram); err_sysram: - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); return ret; } @@ -245,7 +245,7 @@ static int mga_fbdev_destroy(struct drm_device *dev, drm_fb_helper_unregister_fbi(&mfbdev->helper); if (mfb->obj) { - drm_gem_object_unreference_unlocked(mfb->obj); + drm_gem_object_put_unlocked(mfb->obj); mfb->obj = NULL; } drm_fb_helper_fini(&mfbdev->helper); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index dce8a3e..780f983 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -18,7 +18,7 @@ static void mga_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct mga_framebuffer *mga_fb = to_mga_framebuffer(fb); - drm_gem_object_unreference_unlocked(mga_fb->obj); + drm_gem_object_put_unlocked(mga_fb->obj); drm_framebuffer_cleanup(fb); kfree(fb); } @@ -59,13 +59,13 @@ mgag200_user_framebuffer_create(struct drm_device *dev, mga_fb = kzalloc(sizeof(*mga_fb), GFP_KERNEL); if (!mga_fb) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ERR_PTR(-ENOMEM); } ret = mgag200_framebuffer_init(dev, mga_fb, mode_cmd, obj); if (ret) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); kfree(mga_fb); return ERR_PTR(ret); } @@ -317,7 +317,7 @@ int mgag200_dumb_create(struct drm_file *file, return ret; ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); if (ret) return ret; @@ -366,6 +366,6 @@ mgag200_dumb_mmap_offset(struct drm_file *file, bo = gem_to_mga_bo(obj); *offset = mgag200_bo_mmap_offset(bo); - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return 0; } diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index f49f6ac..b0129e7 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -832,7 +832,6 @@ static struct drm_driver msm_driver = { .gem_vm_ops = &vm_ops, .dumb_create = msm_gem_dumb_create, .dumb_map_offset = msm_gem_dumb_map_offset, - .dumb_destroy = drm_gem_dumb_destroy, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = drm_gem_prime_export, diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index 93c38eb..7fbad9c 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -337,8 +337,6 @@ static struct drm_driver mxsfb_driver = { .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = drm_gem_cma_dumb_create, - .dumb_map_offset = drm_gem_cma_dumb_map_offset, - .dumb_destroy = drm_gem_dumb_destroy, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = drm_gem_prime_export, diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index 29653fe..0ea3ca8 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -72,7 +72,7 @@ #define DRIVER_DESC "DRM module for PL111" -static struct drm_mode_config_funcs mode_config_funcs = { +static const struct drm_mode_config_funcs mode_config_funcs = { .fb_create = drm_fb_cma_create, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 403e135..2445e75 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -263,7 +263,6 @@ static struct drm_driver qxl_driver = { .dumb_create = qxl_mode_dumb_create, .dumb_map_offset = qxl_mode_dumb_mmap, - .dumb_destroy = drm_gem_dumb_destroy, #if defined(CONFIG_DEBUG_FS) .debugfs_init = qxl_debugfs_init, #endif diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c index bd87768..7a251a5 100644 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -592,7 +592,7 @@ static void inno_hdmi_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } -static struct drm_connector_funcs inno_hdmi_connector_funcs = { +static const struct drm_connector_funcs inno_hdmi_connector_funcs = { .fill_modes = inno_hdmi_probe_single_connector_modes, .detect = inno_hdmi_connector_detect, .destroy = inno_hdmi_connector_destroy, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index 8a0f756..7077304 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -48,7 +48,7 @@ static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) int i; for (i = 0; i < ROCKCHIP_MAX_FB_BUFFER; i++) - drm_gem_object_unreference_unlocked(rockchip_fb->obj[i]); + drm_gem_object_put_unlocked(rockchip_fb->obj[i]); drm_framebuffer_cleanup(fb); kfree(rockchip_fb); @@ -144,7 +144,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, width * drm_format_plane_cpp(mode_cmd->pixel_format, i); if (obj->size < min_size) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); ret = -EINVAL; goto err_gem_object_unreference; } @@ -161,7 +161,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, err_gem_object_unreference: for (i--; i >= 0; i--) - drm_gem_object_unreference_unlocked(objs[i]); + drm_gem_object_put_unlocked(objs[i]); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c index ce946b9..724579e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c @@ -173,7 +173,7 @@ void rockchip_drm_fbdev_fini(struct drm_device *dev) drm_fb_helper_unregister_fbi(helper); if (helper->fb) - drm_framebuffer_unreference(helper->fb); + drm_framebuffer_put(helper->fb); drm_fb_helper_fini(helper); } diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index f74333e..1869c8b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -383,7 +383,7 @@ rockchip_gem_create_with_handle(struct drm_file *file_priv, goto err_handle_create; /* drop reference from allocate - handle holds it now. */ - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return rk_obj; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 948719d..bf9ed0e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1026,7 +1026,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc, if (old_plane_state->fb == new_plane_state->fb) continue; - drm_framebuffer_reference(old_plane_state->fb); + drm_framebuffer_get(old_plane_state->fb); drm_flip_work_queue(&vop->fb_unref_work, old_plane_state->fb); set_bit(VOP_PENDING_FB_UNREF, &vop->pending); WARN_ON(drm_crtc_vblank_get(crtc) != 0); @@ -1150,7 +1150,7 @@ static void vop_fb_unref_worker(struct drm_flip_work *work, void *val) struct drm_framebuffer *fb = val; drm_crtc_vblank_put(&vop->crtc); - drm_framebuffer_unreference(fb); + drm_framebuffer_put(fb); } static void vop_handle_vblank(struct vop *vop) diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c index 550bb26..42a238b 100644 --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c @@ -119,7 +119,7 @@ sun4i_rgb_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } -static struct drm_connector_funcs sun4i_rgb_con_funcs = { +static const struct drm_connector_funcs sun4i_rgb_con_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .destroy = sun4i_rgb_connector_destroy, .reset = drm_atomic_helper_connector_reset, diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c index 7b45ac9..4edf15e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tv.c +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c @@ -545,7 +545,7 @@ sun4i_tv_comp_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } -static struct drm_connector_funcs sun4i_tv_comp_connector_funcs = { +static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .destroy = sun4i_tv_comp_connector_destroy, .reset = drm_atomic_helper_connector_reset, diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 3ba659a..224ce1d 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1077,8 +1077,6 @@ static struct drm_driver tegra_drm_driver = { .gem_prime_import = tegra_gem_prime_import, .dumb_create = tegra_bo_dumb_create, - .dumb_map_offset = tegra_bo_dumb_map_offset, - .dumb_destroy = drm_gem_dumb_destroy, .ioctls = tegra_drm_ioctls, .num_ioctls = ARRAY_SIZE(tegra_drm_ioctls), diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 7a39a35..c6079af 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -423,27 +423,6 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, return 0; } -int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, - u32 handle, u64 *offset) -{ - struct drm_gem_object *gem; - struct tegra_bo *bo; - - gem = drm_gem_object_lookup(file, handle); - if (!gem) { - dev_err(drm->dev, "failed to lookup GEM object\n"); - return -EINVAL; - } - - bo = to_tegra_bo(gem); - - *offset = drm_vma_node_offset_addr(&bo->gem.vma_node); - - drm_gem_object_unreference_unlocked(gem); - - return 0; -} - static int tegra_bo_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h index 8b32a6f..8eb9fd2 100644 --- a/drivers/gpu/drm/tegra/gem.h +++ b/drivers/gpu/drm/tegra/gem.h @@ -67,8 +67,6 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, void tegra_bo_free_object(struct drm_gem_object *gem); int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, struct drm_mode_create_dumb *args); -int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, - u32 handle, u64 *offset); int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma); diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig index f17c3ca..2e790e7 100644 --- a/drivers/gpu/drm/tinydrm/Kconfig +++ b/drivers/gpu/drm/tinydrm/Kconfig @@ -32,3 +32,13 @@ config TINYDRM_REPAPER 2.71" TFT EPD Panel (E2271CS021) If M is selected the module will be called repaper. + +config TINYDRM_ST7586 + tristate "DRM support for Sitronix ST7586 display panels" + depends on DRM_TINYDRM && SPI + select TINYDRM_MIPI_DBI + help + DRM driver for the following Sitronix ST7586 panels: + * LEGO MINDSTORMS EV3 + + If M is selected the module will be called st7586. diff --git a/drivers/gpu/drm/tinydrm/Makefile b/drivers/gpu/drm/tinydrm/Makefile index 95bb4d4..0c184bd 100644 --- a/drivers/gpu/drm/tinydrm/Makefile +++ b/drivers/gpu/drm/tinydrm/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_TINYDRM_MIPI_DBI) += mipi-dbi.o # Displays obj-$(CONFIG_TINYDRM_MI0283QT) += mi0283qt.o obj-$(CONFIG_TINYDRM_REPAPER) += repaper.o +obj-$(CONFIG_TINYDRM_ST7586) += st7586.o diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c index 75808bb..bd6cce0 100644 --- a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c +++ b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c @@ -185,7 +185,9 @@ EXPORT_SYMBOL(tinydrm_xrgb8888_to_rgb565); /** * tinydrm_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale * @dst: 8-bit grayscale destination buffer + * @vaddr: XRGB8888 source buffer * @fb: DRM framebuffer + * @clip: Clip rectangle area to copy * * Drm doesn't have native monochrome or grayscale support. * Such drivers can announce the commonly supported XR24 format to userspace @@ -195,41 +197,31 @@ EXPORT_SYMBOL(tinydrm_xrgb8888_to_rgb565); * where 1 means foreground color and 0 background color. * * ITU BT.601 is used for the RGB -> luma (brightness) conversion. - * - * Returns: - * Zero on success, negative error code on failure. */ -int tinydrm_xrgb8888_to_gray8(u8 *dst, struct drm_framebuffer *fb) +void tinydrm_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb, + struct drm_clip_rect *clip) { - struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); - struct dma_buf_attachment *import_attach = cma_obj->base.import_attach; - unsigned int x, y, pitch = fb->pitches[0]; - int ret = 0; + unsigned int len = (clip->x2 - clip->x1) * sizeof(u32); + unsigned int x, y; void *buf; u32 *src; if (WARN_ON(fb->format->format != DRM_FORMAT_XRGB8888)) - return -EINVAL; + return; /* * The cma memory is write-combined so reads are uncached. * Speed up by fetching one line at a time. */ - buf = kmalloc(pitch, GFP_KERNEL); + buf = kmalloc(len, GFP_KERNEL); if (!buf) - return -ENOMEM; - - if (import_attach) { - ret = dma_buf_begin_cpu_access(import_attach->dmabuf, - DMA_FROM_DEVICE); - if (ret) - goto err_free; - } + return; - for (y = 0; y < fb->height; y++) { - src = cma_obj->vaddr + (y * pitch); - memcpy(buf, src, pitch); + for (y = clip->y1; y < clip->y2; y++) { + src = vaddr + (y * fb->pitches[0]); + src += clip->x1; + memcpy(buf, src, len); src = buf; - for (x = 0; x < fb->width; x++) { + for (x = clip->x1; x < clip->x2; x++) { u8 r = (*src & 0x00ff0000) >> 16; u8 g = (*src & 0x0000ff00) >> 8; u8 b = *src & 0x000000ff; @@ -240,13 +232,7 @@ int tinydrm_xrgb8888_to_gray8(u8 *dst, struct drm_framebuffer *fb) } } - if (import_attach) - ret = dma_buf_end_cpu_access(import_attach->dmabuf, - DMA_FROM_DEVICE); -err_free: kfree(buf); - - return ret; } EXPORT_SYMBOL(tinydrm_xrgb8888_to_gray8); diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c index f224b54..177e9d8 100644 --- a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c +++ b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c @@ -56,7 +56,7 @@ static const struct drm_connector_helper_funcs tinydrm_connector_hfuncs = { static enum drm_connector_status tinydrm_connector_detect(struct drm_connector *connector, bool force) { - if (drm_device_is_unplugged(connector->dev)) + if (drm_dev_is_unplugged(connector->dev)) return connector_status_disconnected; return connector->status; diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c index 3343d3f..30dc97b 100644 --- a/drivers/gpu/drm/tinydrm/repaper.c +++ b/drivers/gpu/drm/tinydrm/repaper.c @@ -18,6 +18,7 @@ */ #include <linux/delay.h> +#include <linux/dma-buf.h> #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of_device.h> @@ -525,11 +526,20 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb, struct drm_clip_rect *clips, unsigned int num_clips) { + struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); + struct dma_buf_attachment *import_attach = cma_obj->base.import_attach; struct tinydrm_device *tdev = fb->dev->dev_private; struct repaper_epd *epd = epd_from_tinydrm(tdev); + struct drm_clip_rect clip; u8 *buf = NULL; int ret = 0; + /* repaper can't do partial updates */ + clip.x1 = 0; + clip.x2 = fb->width; + clip.y1 = 0; + clip.y2 = fb->height; + mutex_lock(&tdev->dirty_lock); if (!epd->enabled) @@ -550,9 +560,21 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb, goto out_unlock; } - ret = tinydrm_xrgb8888_to_gray8(buf, fb); - if (ret) - goto out_unlock; + if (import_attach) { + ret = dma_buf_begin_cpu_access(import_attach->dmabuf, + DMA_FROM_DEVICE); + if (ret) + goto out_unlock; + } + + tinydrm_xrgb8888_to_gray8(buf, cma_obj->vaddr, fb, &clip); + + if (import_attach) { + ret = dma_buf_end_cpu_access(import_attach->dmabuf, + DMA_FROM_DEVICE); + if (ret) + goto out_unlock; + } repaper_gray8_to_mono_reversed(buf, fb->width, fb->height); diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c new file mode 100644 index 0000000..1b39d3f --- /dev/null +++ b/drivers/gpu/drm/tinydrm/st7586.c @@ -0,0 +1,428 @@ +/* + * DRM driver for Sitronix ST7586 panels + * + * Copyright 2017 David Lechner <david@lechnology.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/delay.h> +#include <linux/dma-buf.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/spi/spi.h> +#include <video/mipi_display.h> + +#include <drm/tinydrm/mipi-dbi.h> +#include <drm/tinydrm/tinydrm-helpers.h> + +/* controller-specific commands */ +#define ST7586_DISP_MODE_GRAY 0x38 +#define ST7586_DISP_MODE_MONO 0x39 +#define ST7586_ENABLE_DDRAM 0x3a +#define ST7586_SET_DISP_DUTY 0xb0 +#define ST7586_SET_PART_DISP 0xb4 +#define ST7586_SET_NLINE_INV 0xb5 +#define ST7586_SET_VOP 0xc0 +#define ST7586_SET_BIAS_SYSTEM 0xc3 +#define ST7586_SET_BOOST_LEVEL 0xc4 +#define ST7586_SET_VOP_OFFSET 0xc7 +#define ST7586_ENABLE_ANALOG 0xd0 +#define ST7586_AUTO_READ_CTRL 0xd7 +#define ST7586_OTP_RW_CTRL 0xe0 +#define ST7586_OTP_CTRL_OUT 0xe1 +#define ST7586_OTP_READ 0xe3 + +#define ST7586_DISP_CTRL_MX BIT(6) +#define ST7586_DISP_CTRL_MY BIT(7) + +/* + * The ST7586 controller has an unusual pixel format where 2bpp grayscale is + * packed 3 pixels per byte with the first two pixels using 3 bits and the 3rd + * pixel using only 2 bits. + * + * | D7 | D6 | D5 || | || 2bpp | + * | (D4) | (D3) | (D2) || D1 | D0 || GRAY | + * +------+------+------++------+------++------+ + * | 1 | 1 | 1 || 1 | 1 || 0 0 | black + * | 1 | 0 | 0 || 1 | 0 || 0 1 | dark gray + * | 0 | 1 | 0 || 0 | 1 || 1 0 | light gray + * | 0 | 0 | 0 || 0 | 0 || 1 1 | white + */ + +static const u8 st7586_lookup[] = { 0x7, 0x4, 0x2, 0x0 }; + +static void st7586_xrgb8888_to_gray332(u8 *dst, void *vaddr, + struct drm_framebuffer *fb, + struct drm_clip_rect *clip) +{ + size_t len = (clip->x2 - clip->x1) * (clip->y2 - clip->y1); + unsigned int x, y; + u8 *src, *buf, val; + + buf = kmalloc(len, GFP_KERNEL); + if (!buf) + return; + + tinydrm_xrgb8888_to_gray8(buf, vaddr, fb, clip); + src = buf; + + for (y = clip->y1; y < clip->y2; y++) { + for (x = clip->x1; x < clip->x2; x += 3) { + val = st7586_lookup[*src++ >> 6] << 5; + val |= st7586_lookup[*src++ >> 6] << 2; + val |= st7586_lookup[*src++ >> 6] >> 1; + *dst++ = val; + } + } + + kfree(buf); +} + +static int st7586_buf_copy(void *dst, struct drm_framebuffer *fb, + struct drm_clip_rect *clip) +{ + struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); + struct dma_buf_attachment *import_attach = cma_obj->base.import_attach; + void *src = cma_obj->vaddr; + int ret = 0; + + if (import_attach) { + ret = dma_buf_begin_cpu_access(import_attach->dmabuf, + DMA_FROM_DEVICE); + if (ret) + return ret; + } + + st7586_xrgb8888_to_gray332(dst, src, fb, clip); + + if (import_attach) + ret = dma_buf_end_cpu_access(import_attach->dmabuf, + DMA_FROM_DEVICE); + + return ret; +} + +static int st7586_fb_dirty(struct drm_framebuffer *fb, + struct drm_file *file_priv, unsigned int flags, + unsigned int color, struct drm_clip_rect *clips, + unsigned int num_clips) +{ + struct tinydrm_device *tdev = fb->dev->dev_private; + struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev); + struct drm_clip_rect clip; + int start, end; + int ret = 0; + + mutex_lock(&tdev->dirty_lock); + + if (!mipi->enabled) + goto out_unlock; + + /* fbdev can flush even when we're not interested */ + if (tdev->pipe.plane.fb != fb) + goto out_unlock; + + tinydrm_merge_clips(&clip, clips, num_clips, flags, fb->width, + fb->height); + + /* 3 pixels per byte, so grow clip to nearest multiple of 3 */ + clip.x1 = rounddown(clip.x1, 3); + clip.x2 = roundup(clip.x2, 3); + + DRM_DEBUG("Flushing [FB:%d] x1=%u, x2=%u, y1=%u, y2=%u\n", fb->base.id, + clip.x1, clip.x2, clip.y1, clip.y2); + + ret = st7586_buf_copy(mipi->tx_buf, fb, &clip); + if (ret) + goto out_unlock; + + /* Pixels are packed 3 per byte */ + start = clip.x1 / 3; + end = clip.x2 / 3; + + mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS, + (start >> 8) & 0xFF, start & 0xFF, + (end >> 8) & 0xFF, (end - 1) & 0xFF); + mipi_dbi_command(mipi, MIPI_DCS_SET_PAGE_ADDRESS, + (clip.y1 >> 8) & 0xFF, clip.y1 & 0xFF, + (clip.y2 >> 8) & 0xFF, (clip.y2 - 1) & 0xFF); + + ret = mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START, + (u8 *)mipi->tx_buf, + (end - start) * (clip.y2 - clip.y1)); + +out_unlock: + mutex_unlock(&tdev->dirty_lock); + + if (ret) + dev_err_once(fb->dev->dev, "Failed to update display %d\n", + ret); + + return ret; +} + +static const struct drm_framebuffer_funcs st7586_fb_funcs = { + .destroy = drm_fb_cma_destroy, + .create_handle = drm_fb_cma_create_handle, + .dirty = st7586_fb_dirty, +}; + +void st7586_pipe_enable(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *crtc_state) +{ + struct tinydrm_device *tdev = pipe_to_tinydrm(pipe); + struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev); + struct drm_framebuffer *fb = pipe->plane.fb; + struct device *dev = tdev->drm->dev; + int ret; + u8 addr_mode; + + DRM_DEBUG_KMS("\n"); + + mipi_dbi_hw_reset(mipi); + ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f); + if (ret) { + dev_err(dev, "Error sending command %d\n", ret); + return; + } + + mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00); + + msleep(10); + + mipi_dbi_command(mipi, ST7586_OTP_READ); + + msleep(20); + + mipi_dbi_command(mipi, ST7586_OTP_CTRL_OUT); + mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE); + mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF); + + msleep(50); + + mipi_dbi_command(mipi, ST7586_SET_VOP_OFFSET, 0x00); + mipi_dbi_command(mipi, ST7586_SET_VOP, 0xe3, 0x00); + mipi_dbi_command(mipi, ST7586_SET_BIAS_SYSTEM, 0x02); + mipi_dbi_command(mipi, ST7586_SET_BOOST_LEVEL, 0x04); + mipi_dbi_command(mipi, ST7586_ENABLE_ANALOG, 0x1d); + mipi_dbi_command(mipi, ST7586_SET_NLINE_INV, 0x00); + mipi_dbi_command(mipi, ST7586_DISP_MODE_GRAY); + mipi_dbi_command(mipi, ST7586_ENABLE_DDRAM, 0x02); + + switch (mipi->rotation) { + default: + addr_mode = 0x00; + break; + case 90: + addr_mode = ST7586_DISP_CTRL_MY; + break; + case 180: + addr_mode = ST7586_DISP_CTRL_MX | ST7586_DISP_CTRL_MY; + break; + case 270: + addr_mode = ST7586_DISP_CTRL_MX; + break; + } + mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode); + + mipi_dbi_command(mipi, ST7586_SET_DISP_DUTY, 0x7f); + mipi_dbi_command(mipi, ST7586_SET_PART_DISP, 0xa0); + mipi_dbi_command(mipi, MIPI_DCS_SET_PARTIAL_AREA, 0x00, 0x00, 0x00, 0x77); + mipi_dbi_command(mipi, MIPI_DCS_EXIT_INVERT_MODE); + + msleep(100); + + mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON); + + mipi->enabled = true; + + if (fb) + fb->funcs->dirty(fb, NULL, 0, 0, NULL, 0); +} + +static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe) +{ + struct tinydrm_device *tdev = pipe_to_tinydrm(pipe); + struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev); + + DRM_DEBUG_KMS("\n"); + + if (!mipi->enabled) + return; + + mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF); + mipi->enabled = false; +} + +static const u32 st7586_formats[] = { + DRM_FORMAT_XRGB8888, +}; + +static int st7586_init(struct device *dev, struct mipi_dbi *mipi, + const struct drm_simple_display_pipe_funcs *pipe_funcs, + struct drm_driver *driver, const struct drm_display_mode *mode, + unsigned int rotation) +{ + size_t bufsize = (mode->vdisplay + 2) / 3 * mode->hdisplay; + struct tinydrm_device *tdev = &mipi->tinydrm; + int ret; + + mutex_init(&mipi->cmdlock); + + mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL); + if (!mipi->tx_buf) + return -ENOMEM; + + ret = devm_tinydrm_init(dev, tdev, &st7586_fb_funcs, driver); + if (ret) + return ret; + + ret = tinydrm_display_pipe_init(tdev, pipe_funcs, + DRM_MODE_CONNECTOR_VIRTUAL, + st7586_formats, + ARRAY_SIZE(st7586_formats), + mode, rotation); + if (ret) + return ret; + + tdev->drm->mode_config.preferred_depth = 32; + mipi->rotation = rotation; + + drm_mode_config_reset(tdev->drm); + + DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n", + tdev->drm->mode_config.preferred_depth, rotation); + + return 0; +} + +static const struct drm_simple_display_pipe_funcs st7586_pipe_funcs = { + .enable = st7586_pipe_enable, + .disable = st7586_pipe_disable, + .update = tinydrm_display_pipe_update, + .prepare_fb = tinydrm_display_pipe_prepare_fb, +}; + +static const struct drm_display_mode st7586_mode = { + TINYDRM_MODE(178, 128, 37, 27), +}; + +DEFINE_DRM_GEM_CMA_FOPS(st7586_fops); + +static struct drm_driver st7586_driver = { + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | + DRIVER_ATOMIC, + .fops = &st7586_fops, + TINYDRM_GEM_DRIVER_OPS, + .lastclose = tinydrm_lastclose, + .debugfs_init = mipi_dbi_debugfs_init, + .name = "st7586", + .desc = "Sitronix ST7586", + .date = "20170801", + .major = 1, + .minor = 0, +}; + +static const struct of_device_id st7586_of_match[] = { + { .compatible = "lego,ev3-lcd" }, + {}, +}; +MODULE_DEVICE_TABLE(of, st7586_of_match); + +static const struct spi_device_id st7586_id[] = { + { "ev3-lcd", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(spi, st7586_id); + +static int st7586_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct tinydrm_device *tdev; + struct mipi_dbi *mipi; + struct gpio_desc *a0; + u32 rotation = 0; + int ret; + + mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL); + if (!mipi) + return -ENOMEM; + + mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(mipi->reset)) { + dev_err(dev, "Failed to get gpio 'reset'\n"); + return PTR_ERR(mipi->reset); + } + + a0 = devm_gpiod_get(dev, "a0", GPIOD_OUT_LOW); + if (IS_ERR(a0)) { + dev_err(dev, "Failed to get gpio 'a0'\n"); + return PTR_ERR(a0); + } + + device_property_read_u32(dev, "rotation", &rotation); + + ret = mipi_dbi_spi_init(spi, mipi, a0); + if (ret) + return ret; + + /* Cannot read from this controller via SPI */ + mipi->read_commands = NULL; + + /* + * we are using 8-bit data, so we are not actually swapping anything, + * but setting mipi->swap_bytes makes mipi_dbi_typec3_command() do the + * right thing and not use 16-bit transfers (which results in swapped + * bytes on little-endian systems and causes out of order data to be + * sent to the display). + */ + mipi->swap_bytes = true; + + ret = st7586_init(&spi->dev, mipi, &st7586_pipe_funcs, &st7586_driver, + &st7586_mode, rotation); + if (ret) + return ret; + + tdev = &mipi->tinydrm; + + ret = devm_tinydrm_register(tdev); + if (ret) + return ret; + + spi_set_drvdata(spi, mipi); + + DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n", + tdev->drm->driver->name, dev_name(dev), + spi->max_speed_hz / 1000000, + tdev->drm->primary->index); + + return 0; +} + +static void st7586_shutdown(struct spi_device *spi) +{ + struct mipi_dbi *mipi = spi_get_drvdata(spi); + + tinydrm_shutdown(&mipi->tinydrm); +} + +static struct spi_driver st7586_spi_driver = { + .driver = { + .name = "st7586", + .owner = THIS_MODULE, + .of_match_table = st7586_of_match, + }, + .id_table = st7586_id, + .probe = st7586_probe, + .shutdown = st7586_shutdown, +}; +module_spi_driver(st7586_spi_driver); + +MODULE_DESCRIPTION("Sitronix ST7586 DRM driver"); +MODULE_AUTHOR("David Lechner <david@lechnology.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index d2f57c5..9f9a497 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -96,7 +96,7 @@ static int udl_mode_valid(struct drm_connector *connector, static enum drm_connector_status udl_detect(struct drm_connector *connector, bool force) { - if (drm_device_is_unplugged(connector->dev)) + if (drm_dev_is_unplugged(connector->dev)) return connector_status_disconnected; return connector_status_connected; } diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 0f02e1ac..bfacb29 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -54,7 +54,6 @@ static struct drm_driver driver = { .dumb_create = udl_dumb_create, .dumb_map_offset = udl_gem_mmap, - .dumb_destroy = drm_gem_dumb_destroy, .fops = &udl_driver_fops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, @@ -102,7 +101,7 @@ static void udl_usb_disconnect(struct usb_interface *interface) drm_kms_helper_poll_disable(dev); udl_fbdev_unplug(dev); udl_drop_usb(dev); - drm_unplug_dev(dev); + drm_dev_unplug(dev); } /* diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index a5c54dc..b7ca90d 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -198,7 +198,7 @@ static int udl_fb_open(struct fb_info *info, int user) struct udl_device *udl = dev->dev_private; /* If the USB device is gone, we don't accept new opens */ - if (drm_device_is_unplugged(udl->ddev)) + if (drm_dev_is_unplugged(udl->ddev)) return -ENODEV; ufbdev->fb_count++; @@ -309,7 +309,7 @@ static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb) struct udl_framebuffer *ufb = to_udl_fb(fb); if (ufb->obj) - drm_gem_object_unreference_unlocked(&ufb->obj->base); + drm_gem_object_put_unlocked(&ufb->obj->base); drm_framebuffer_cleanup(fb); kfree(ufb); @@ -403,7 +403,7 @@ static int udlfb_create(struct drm_fb_helper *helper, return ret; out_gfree: - drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base); + drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); out: return ret; } @@ -419,7 +419,7 @@ static void udl_fbdev_destroy(struct drm_device *dev, drm_fb_helper_fini(&ufbdev->helper); drm_framebuffer_unregister_private(&ufbdev->ufb.base); drm_framebuffer_cleanup(&ufbdev->ufb.base); - drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base); + drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); } int udl_fbdev_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index db9cece..dee6bd9 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -52,7 +52,7 @@ udl_gem_create(struct drm_file *file, return ret; } - drm_gem_object_unreference_unlocked(&obj->base); + drm_gem_object_put_unlocked(&obj->base); *handle_p = handle; return 0; } @@ -234,7 +234,7 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, *offset = drm_vma_node_offset_addr(&gobj->base.vma_node); out: - drm_gem_object_unreference(&gobj->base); + drm_gem_object_put(&gobj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index b24dd86..3afdbf4 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -366,7 +366,7 @@ int vc4_dumb_create(struct drm_file *file_priv, return PTR_ERR(bo); ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); - drm_gem_object_unreference_unlocked(&bo->base.base); + drm_gem_object_put_unlocked(&bo->base.base); return ret; } @@ -482,7 +482,7 @@ vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) struct vc4_bo *bo = to_vc4_bo(obj); if (bo->validated_shader) { - DRM_ERROR("Attempting to export shader BO\n"); + DRM_DEBUG("Attempting to export shader BO\n"); return ERR_PTR(-EINVAL); } @@ -503,7 +503,7 @@ int vc4_mmap(struct file *filp, struct vm_area_struct *vma) bo = to_vc4_bo(gem_obj); if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { - DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); + DRM_DEBUG("mmaping of shader BOs for writing not allowed.\n"); return -EINVAL; } @@ -528,7 +528,7 @@ int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) struct vc4_bo *bo = to_vc4_bo(obj); if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { - DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); + DRM_DEBUG("mmaping of shader BOs for writing not allowed.\n"); return -EINVAL; } @@ -540,7 +540,7 @@ void *vc4_prime_vmap(struct drm_gem_object *obj) struct vc4_bo *bo = to_vc4_bo(obj); if (bo->validated_shader) { - DRM_ERROR("mmaping of shader BOs not allowed.\n"); + DRM_DEBUG("mmaping of shader BOs not allowed.\n"); return ERR_PTR(-EINVAL); } @@ -581,7 +581,7 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, return PTR_ERR(bo); ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); - drm_gem_object_unreference_unlocked(&bo->base.base); + drm_gem_object_put_unlocked(&bo->base.base); return ret; } @@ -594,14 +594,14 @@ int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, gem_obj = drm_gem_object_lookup(file_priv, args->handle); if (!gem_obj) { - DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); + DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); return -EINVAL; } /* The mmap offset was set up at BO allocation time. */ args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); - drm_gem_object_unreference_unlocked(gem_obj); + drm_gem_object_put_unlocked(gem_obj); return 0; } @@ -657,7 +657,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); fail: - drm_gem_object_unreference_unlocked(&bo->base.base); + drm_gem_object_put_unlocked(&bo->base.base); return ret; } @@ -698,13 +698,13 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, gem_obj = drm_gem_object_lookup(file_priv, args->handle); if (!gem_obj) { - DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); + DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); return -ENOENT; } bo = to_vc4_bo(gem_obj); bo->t_format = t_format; - drm_gem_object_unreference_unlocked(gem_obj); + drm_gem_object_put_unlocked(gem_obj); return 0; } @@ -729,7 +729,7 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, gem_obj = drm_gem_object_lookup(file_priv, args->handle); if (!gem_obj) { - DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); + DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); return -ENOENT; } bo = to_vc4_bo(gem_obj); @@ -739,7 +739,7 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, else args->modifier = DRM_FORMAT_MOD_NONE; - drm_gem_object_unreference_unlocked(gem_obj); + drm_gem_object_put_unlocked(gem_obj); return 0; } @@ -830,7 +830,7 @@ int vc4_label_bo_ioctl(struct drm_device *dev, void *data, ret = -ENOMEM; mutex_unlock(&vc4->bo_lock); - drm_gem_object_unreference_unlocked(gem_obj); + drm_gem_object_put_unlocked(gem_obj); return ret; } diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 664a55b..ce1e3b9 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -763,7 +763,7 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) } drm_crtc_vblank_put(crtc); - drm_framebuffer_unreference(flip_state->fb); + drm_framebuffer_put(flip_state->fb); kfree(flip_state); up(&vc4->async_modeset); @@ -792,7 +792,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, if (!flip_state) return -ENOMEM; - drm_framebuffer_reference(fb); + drm_framebuffer_get(fb); flip_state->fb = fb; flip_state->crtc = crtc; flip_state->event = event; @@ -800,7 +800,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, /* Make sure all other async modesetes have landed. */ ret = down_interruptible(&vc4->async_modeset); if (ret) { - drm_framebuffer_unreference(fb); + drm_framebuffer_put(fb); kfree(flip_state); return ret; } diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index e8f0e17..1c96edc 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -99,6 +99,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data, case DRM_VC4_PARAM_SUPPORTS_BRANCHES: case DRM_VC4_PARAM_SUPPORTS_ETC1: case DRM_VC4_PARAM_SUPPORTS_THREADED_FS: + case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER: args->value = true; break; default: diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 629d372..d1e0dc9 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1636,14 +1636,10 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master, pm_runtime_disable(dev); - drm_bridge_remove(dsi->bridge); vc4_dsi_encoder_destroy(dsi->encoder); mipi_dsi_host_unregister(&dsi->dsi_host); - clk_disable_unprepare(dsi->pll_phy_clock); - clk_disable_unprepare(dsi->escape_clock); - if (dsi->port == 1) vc4->dsi1 = NULL; } diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 209fccd..d0c6bfb 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -55,7 +55,7 @@ vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state) unsigned int i; for (i = 0; i < state->user_state.bo_count; i++) - drm_gem_object_unreference_unlocked(state->bo[i]); + drm_gem_object_put_unlocked(state->bo[i]); kfree(state); } @@ -188,12 +188,12 @@ vc4_save_hang_state(struct drm_device *dev) continue; for (j = 0; j < exec[i]->bo_count; j++) { - drm_gem_object_reference(&exec[i]->bo[j]->base); + drm_gem_object_get(&exec[i]->bo[j]->base); kernel_state->bo[j + prev_idx] = &exec[i]->bo[j]->base; } list_for_each_entry(bo, &exec[i]->unref_list, unref_head) { - drm_gem_object_reference(&bo->base.base); + drm_gem_object_get(&bo->base.base); kernel_state->bo[j + prev_idx] = &bo->base.base; j++; } @@ -659,7 +659,7 @@ vc4_cl_lookup_bos(struct drm_device *dev, /* See comment on bo_index for why we have to check * this. */ - DRM_ERROR("Rendering requires BOs to validate\n"); + DRM_DEBUG("Rendering requires BOs to validate\n"); return -EINVAL; } @@ -690,13 +690,13 @@ vc4_cl_lookup_bos(struct drm_device *dev, struct drm_gem_object *bo = idr_find(&file_priv->object_idr, handles[i]); if (!bo) { - DRM_ERROR("Failed to look up GEM BO %d: %d\n", + DRM_DEBUG("Failed to look up GEM BO %d: %d\n", i, handles[i]); ret = -EINVAL; spin_unlock(&file_priv->table_lock); goto fail; } - drm_gem_object_reference(bo); + drm_gem_object_get(bo); exec->bo[i] = (struct drm_gem_cma_object *)bo; } spin_unlock(&file_priv->table_lock); @@ -728,7 +728,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) args->shader_rec_count >= (UINT_MAX / sizeof(struct vc4_shader_state)) || temp_size < exec_size) { - DRM_ERROR("overflow in exec arguments\n"); + DRM_DEBUG("overflow in exec arguments\n"); ret = -EINVAL; goto fail; } @@ -834,7 +834,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) if (exec->bo) { for (i = 0; i < exec->bo_count; i++) - drm_gem_object_unreference_unlocked(&exec->bo[i]->base); + drm_gem_object_put_unlocked(&exec->bo[i]->base); kvfree(exec->bo); } @@ -842,7 +842,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) struct vc4_bo *bo = list_first_entry(&exec->unref_list, struct vc4_bo, unref_head); list_del(&bo->unref_head); - drm_gem_object_unreference_unlocked(&bo->base.base); + drm_gem_object_put_unlocked(&bo->base.base); } /* Free up the allocation of any bin slots we used. */ @@ -973,7 +973,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, gem_obj = drm_gem_object_lookup(file_priv, args->handle); if (!gem_obj) { - DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); + DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); return -EINVAL; } bo = to_vc4_bo(gem_obj); @@ -981,7 +981,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno, &args->timeout_ns); - drm_gem_object_unreference_unlocked(gem_obj); + drm_gem_object_put_unlocked(gem_obj); return ret; } @@ -1007,8 +1007,11 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, struct ww_acquire_ctx acquire_ctx; int ret = 0; - if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) { - DRM_ERROR("Unknown flags: 0x%02x\n", args->flags); + if ((args->flags & ~(VC4_SUBMIT_CL_USE_CLEAR_COLOR | + VC4_SUBMIT_CL_FIXED_RCL_ORDER | + VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X | + VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y)) != 0) { + DRM_DEBUG("Unknown flags: 0x%02x\n", args->flags); return -EINVAL; } @@ -1117,6 +1120,4 @@ vc4_gem_destroy(struct drm_device *dev) if (vc4->hang_state) vc4_free_hang_state(dev, vc4->hang_state); - - vc4_bo_cache_destroy(dev); } diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index ff09b8e..937da8d 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -288,6 +288,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) drm_mode_connector_update_edid_property(connector, edid); ret = drm_add_edid_modes(connector, edid); drm_edid_to_eld(connector, edid); + kfree(edid); return ret; } diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index aeec6e8..dfe7554 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -169,7 +169,7 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev, gem_obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); if (!gem_obj) { - DRM_ERROR("Failed to look up GEM BO %d\n", + DRM_DEBUG("Failed to look up GEM BO %d\n", mode_cmd->handles[0]); return ERR_PTR(-ENOENT); } @@ -184,7 +184,7 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev, mode_cmd_local.modifier[0] = DRM_FORMAT_MOD_NONE; } - drm_gem_object_unreference_unlocked(gem_obj); + drm_gem_object_put_unlocked(gem_obj); mode_cmd = &mode_cmd_local; } diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c index 4a80515..273984f 100644 --- a/drivers/gpu/drm/vc4/vc4_render_cl.c +++ b/drivers/gpu/drm/vc4/vc4_render_cl.c @@ -261,8 +261,17 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, uint8_t max_y_tile = args->max_y_tile; uint8_t xtiles = max_x_tile - min_x_tile + 1; uint8_t ytiles = max_y_tile - min_y_tile + 1; - uint8_t x, y; + uint8_t xi, yi; uint32_t size, loop_body_size; + bool positive_x = true; + bool positive_y = true; + + if (args->flags & VC4_SUBMIT_CL_FIXED_RCL_ORDER) { + if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X)) + positive_x = false; + if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y)) + positive_y = false; + } size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE; loop_body_size = VC4_PACKET_TILE_COORDINATES_SIZE; @@ -354,10 +363,12 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, rcl_u16(setup, args->height); rcl_u16(setup, args->color_write.bits); - for (y = min_y_tile; y <= max_y_tile; y++) { - for (x = min_x_tile; x <= max_x_tile; x++) { - bool first = (x == min_x_tile && y == min_y_tile); - bool last = (x == max_x_tile && y == max_y_tile); + for (yi = 0; yi < ytiles; yi++) { + int y = positive_y ? min_y_tile + yi : max_y_tile - yi; + for (xi = 0; xi < xtiles; xi++) { + int x = positive_x ? min_x_tile + xi : max_x_tile - xi; + bool first = (xi == 0 && yi == 0); + bool last = (xi == xtiles - 1 && yi == ytiles - 1); emit_tile(exec, setup, x, y, first, last); } @@ -378,14 +389,14 @@ static int vc4_full_res_bounds_check(struct vc4_exec_info *exec, u32 render_tiles_stride = DIV_ROUND_UP(exec->args->width, 32); if (surf->offset > obj->base.size) { - DRM_ERROR("surface offset %d > BO size %zd\n", + DRM_DEBUG("surface offset %d > BO size %zd\n", surf->offset, obj->base.size); return -EINVAL; } if ((obj->base.size - surf->offset) / VC4_TILE_BUFFER_SIZE < render_tiles_stride * args->max_y_tile + args->max_x_tile) { - DRM_ERROR("MSAA tile %d, %d out of bounds " + DRM_DEBUG("MSAA tile %d, %d out of bounds " "(bo size %zd, offset %d).\n", args->max_x_tile, args->max_y_tile, obj->base.size, @@ -401,7 +412,7 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec, struct drm_vc4_submit_rcl_surface *surf) { if (surf->flags != 0 || surf->bits != 0) { - DRM_ERROR("MSAA surface had nonzero flags/bits\n"); + DRM_DEBUG("MSAA surface had nonzero flags/bits\n"); return -EINVAL; } @@ -415,7 +426,7 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec, exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; if (surf->offset & 0xf) { - DRM_ERROR("MSAA write must be 16b aligned.\n"); + DRM_DEBUG("MSAA write must be 16b aligned.\n"); return -EINVAL; } @@ -437,7 +448,7 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, int ret; if (surf->flags & ~VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { - DRM_ERROR("Extra flags set\n"); + DRM_DEBUG("Extra flags set\n"); return -EINVAL; } @@ -453,12 +464,12 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { if (surf == &exec->args->zs_write) { - DRM_ERROR("general zs write may not be a full-res.\n"); + DRM_DEBUG("general zs write may not be a full-res.\n"); return -EINVAL; } if (surf->bits != 0) { - DRM_ERROR("load/store general bits set with " + DRM_DEBUG("load/store general bits set with " "full res load/store.\n"); return -EINVAL; } @@ -473,19 +484,19 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK | VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK | VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) { - DRM_ERROR("Unknown bits in load/store: 0x%04x\n", + DRM_DEBUG("Unknown bits in load/store: 0x%04x\n", surf->bits); return -EINVAL; } if (tiling > VC4_TILING_FORMAT_LT) { - DRM_ERROR("Bad tiling format\n"); + DRM_DEBUG("Bad tiling format\n"); return -EINVAL; } if (buffer == VC4_LOADSTORE_TILE_BUFFER_ZS) { if (format != 0) { - DRM_ERROR("No color format should be set for ZS\n"); + DRM_DEBUG("No color format should be set for ZS\n"); return -EINVAL; } cpp = 4; @@ -499,16 +510,16 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, cpp = 4; break; default: - DRM_ERROR("Bad tile buffer format\n"); + DRM_DEBUG("Bad tile buffer format\n"); return -EINVAL; } } else { - DRM_ERROR("Bad load/store buffer %d.\n", buffer); + DRM_DEBUG("Bad load/store buffer %d.\n", buffer); return -EINVAL; } if (surf->offset & 0xf) { - DRM_ERROR("load/store buffer must be 16b aligned.\n"); + DRM_DEBUG("load/store buffer must be 16b aligned.\n"); return -EINVAL; } @@ -533,7 +544,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, int cpp; if (surf->flags != 0) { - DRM_ERROR("No flags supported on render config.\n"); + DRM_DEBUG("No flags supported on render config.\n"); return -EINVAL; } @@ -541,7 +552,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, VC4_RENDER_CONFIG_FORMAT_MASK | VC4_RENDER_CONFIG_MS_MODE_4X | VC4_RENDER_CONFIG_DECIMATE_MODE_4X)) { - DRM_ERROR("Unknown bits in render config: 0x%04x\n", + DRM_DEBUG("Unknown bits in render config: 0x%04x\n", surf->bits); return -EINVAL; } @@ -556,7 +567,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj; if (tiling > VC4_TILING_FORMAT_LT) { - DRM_ERROR("Bad tiling format\n"); + DRM_DEBUG("Bad tiling format\n"); return -EINVAL; } @@ -569,7 +580,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, cpp = 4; break; default: - DRM_ERROR("Bad tile buffer format\n"); + DRM_DEBUG("Bad tile buffer format\n"); return -EINVAL; } @@ -590,7 +601,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) if (args->min_x_tile > args->max_x_tile || args->min_y_tile > args->max_y_tile) { - DRM_ERROR("Bad render tile set (%d,%d)-(%d,%d)\n", + DRM_DEBUG("Bad render tile set (%d,%d)-(%d,%d)\n", args->min_x_tile, args->min_y_tile, args->max_x_tile, args->max_y_tile); return -EINVAL; @@ -599,7 +610,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) if (has_bin && (args->max_x_tile > exec->bin_tiles_x || args->max_y_tile > exec->bin_tiles_y)) { - DRM_ERROR("Render tiles (%d,%d) outside of bin config " + DRM_DEBUG("Render tiles (%d,%d) outside of bin config " "(%d,%d)\n", args->max_x_tile, args->max_y_tile, exec->bin_tiles_x, exec->bin_tiles_y); @@ -642,7 +653,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) */ if (!setup.color_write && !setup.zs_write && !setup.msaa_color_write && !setup.msaa_zs_write) { - DRM_ERROR("RCL requires color or Z/S write\n"); + DRM_DEBUG("RCL requires color or Z/S write\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c index 814b512..2db485a 100644 --- a/drivers/gpu/drm/vc4/vc4_validate.c +++ b/drivers/gpu/drm/vc4/vc4_validate.c @@ -109,7 +109,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) struct vc4_bo *bo; if (hindex >= exec->bo_count) { - DRM_ERROR("BO index %d greater than BO count %d\n", + DRM_DEBUG("BO index %d greater than BO count %d\n", hindex, exec->bo_count); return NULL; } @@ -117,7 +117,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) bo = to_vc4_bo(&obj->base); if (bo->validated_shader) { - DRM_ERROR("Trying to use shader BO as something other than " + DRM_DEBUG("Trying to use shader BO as something other than " "a shader\n"); return NULL; } @@ -172,7 +172,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, * our math. */ if (width > 4096 || height > 4096) { - DRM_ERROR("Surface dimensions (%d,%d) too large", + DRM_DEBUG("Surface dimensions (%d,%d) too large", width, height); return false; } @@ -191,7 +191,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, aligned_height = round_up(height, utile_h); break; default: - DRM_ERROR("buffer tiling %d unsupported\n", tiling_format); + DRM_DEBUG("buffer tiling %d unsupported\n", tiling_format); return false; } @@ -200,7 +200,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, if (size + offset < size || size + offset > fbo->base.size) { - DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n", + DRM_DEBUG("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n", width, height, aligned_width, aligned_height, size, offset, fbo->base.size); @@ -214,7 +214,7 @@ static int validate_flush(VALIDATE_ARGS) { if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 1)) { - DRM_ERROR("Bin CL must end with VC4_PACKET_FLUSH\n"); + DRM_DEBUG("Bin CL must end with VC4_PACKET_FLUSH\n"); return -EINVAL; } exec->found_flush = true; @@ -226,13 +226,13 @@ static int validate_start_tile_binning(VALIDATE_ARGS) { if (exec->found_start_tile_binning_packet) { - DRM_ERROR("Duplicate VC4_PACKET_START_TILE_BINNING\n"); + DRM_DEBUG("Duplicate VC4_PACKET_START_TILE_BINNING\n"); return -EINVAL; } exec->found_start_tile_binning_packet = true; if (!exec->found_tile_binning_mode_config_packet) { - DRM_ERROR("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); + DRM_DEBUG("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); return -EINVAL; } @@ -243,7 +243,7 @@ static int validate_increment_semaphore(VALIDATE_ARGS) { if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 2)) { - DRM_ERROR("Bin CL must end with " + DRM_DEBUG("Bin CL must end with " "VC4_PACKET_INCREMENT_SEMAPHORE\n"); return -EINVAL; } @@ -264,7 +264,7 @@ validate_indexed_prim_list(VALIDATE_ARGS) /* Check overflow condition */ if (exec->shader_state_count == 0) { - DRM_ERROR("shader state must precede primitives\n"); + DRM_DEBUG("shader state must precede primitives\n"); return -EINVAL; } shader_state = &exec->shader_state[exec->shader_state_count - 1]; @@ -281,7 +281,7 @@ validate_indexed_prim_list(VALIDATE_ARGS) if (offset > ib->base.size || (ib->base.size - offset) / index_size < length) { - DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n", + DRM_DEBUG("IB access overflow (%d + %d*%d > %zd)\n", offset, length, index_size, ib->base.size); return -EINVAL; } @@ -301,13 +301,13 @@ validate_gl_array_primitive(VALIDATE_ARGS) /* Check overflow condition */ if (exec->shader_state_count == 0) { - DRM_ERROR("shader state must precede primitives\n"); + DRM_DEBUG("shader state must precede primitives\n"); return -EINVAL; } shader_state = &exec->shader_state[exec->shader_state_count - 1]; if (length + base_index < length) { - DRM_ERROR("primitive vertex count overflow\n"); + DRM_DEBUG("primitive vertex count overflow\n"); return -EINVAL; } max_index = length + base_index - 1; @@ -324,7 +324,7 @@ validate_gl_shader_state(VALIDATE_ARGS) uint32_t i = exec->shader_state_count++; if (i >= exec->shader_state_size) { - DRM_ERROR("More requests for shader states than declared\n"); + DRM_DEBUG("More requests for shader states than declared\n"); return -EINVAL; } @@ -332,7 +332,7 @@ validate_gl_shader_state(VALIDATE_ARGS) exec->shader_state[i].max_index = 0; if (exec->shader_state[i].addr & ~0xf) { - DRM_ERROR("high bits set in GL shader rec reference\n"); + DRM_DEBUG("high bits set in GL shader rec reference\n"); return -EINVAL; } @@ -356,7 +356,7 @@ validate_tile_binning_config(VALIDATE_ARGS) int bin_slot; if (exec->found_tile_binning_mode_config_packet) { - DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); + DRM_DEBUG("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); return -EINVAL; } exec->found_tile_binning_mode_config_packet = true; @@ -368,14 +368,14 @@ validate_tile_binning_config(VALIDATE_ARGS) if (exec->bin_tiles_x == 0 || exec->bin_tiles_y == 0) { - DRM_ERROR("Tile binning config of %dx%d too small\n", + DRM_DEBUG("Tile binning config of %dx%d too small\n", exec->bin_tiles_x, exec->bin_tiles_y); return -EINVAL; } if (flags & (VC4_BIN_CONFIG_DB_NON_MS | VC4_BIN_CONFIG_TILE_BUFFER_64BIT)) { - DRM_ERROR("unsupported binning config flags 0x%02x\n", flags); + DRM_DEBUG("unsupported binning config flags 0x%02x\n", flags); return -EINVAL; } @@ -493,20 +493,20 @@ vc4_validate_bin_cl(struct drm_device *dev, const struct cmd_info *info; if (cmd >= ARRAY_SIZE(cmd_info)) { - DRM_ERROR("0x%08x: packet %d out of bounds\n", + DRM_DEBUG("0x%08x: packet %d out of bounds\n", src_offset, cmd); return -EINVAL; } info = &cmd_info[cmd]; if (!info->name) { - DRM_ERROR("0x%08x: packet %d invalid\n", + DRM_DEBUG("0x%08x: packet %d invalid\n", src_offset, cmd); return -EINVAL; } if (src_offset + info->len > len) { - DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x " + DRM_DEBUG("0x%08x: packet %d (%s) length 0x%08x " "exceeds bounds (0x%08x)\n", src_offset, cmd, info->name, info->len, src_offset + len); @@ -519,7 +519,7 @@ vc4_validate_bin_cl(struct drm_device *dev, if (info->func && info->func(exec, dst_pkt + 1, src_pkt + 1)) { - DRM_ERROR("0x%08x: packet %d (%s) failed to validate\n", + DRM_DEBUG("0x%08x: packet %d (%s) failed to validate\n", src_offset, cmd, info->name); return -EINVAL; } @@ -537,7 +537,7 @@ vc4_validate_bin_cl(struct drm_device *dev, exec->ct0ea = exec->ct0ca + dst_offset; if (!exec->found_start_tile_binning_packet) { - DRM_ERROR("Bin CL missing VC4_PACKET_START_TILE_BINNING\n"); + DRM_DEBUG("Bin CL missing VC4_PACKET_START_TILE_BINNING\n"); return -EINVAL; } @@ -549,7 +549,7 @@ vc4_validate_bin_cl(struct drm_device *dev, * semaphore increment. */ if (!exec->found_increment_semaphore_packet || !exec->found_flush) { - DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE + " + DRM_DEBUG("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE + " "VC4_PACKET_FLUSH\n"); return -EINVAL; } @@ -588,11 +588,11 @@ reloc_tex(struct vc4_exec_info *exec, uint32_t remaining_size = tex->base.size - p0; if (p0 > tex->base.size - 4) { - DRM_ERROR("UBO offset greater than UBO size\n"); + DRM_DEBUG("UBO offset greater than UBO size\n"); goto fail; } if (p1 > remaining_size - 4) { - DRM_ERROR("UBO clamp would allow reads " + DRM_DEBUG("UBO clamp would allow reads " "outside of UBO\n"); goto fail; } @@ -612,14 +612,14 @@ reloc_tex(struct vc4_exec_info *exec, if (VC4_GET_FIELD(p3, VC4_TEX_P2_PTYPE) == VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE) { if (cube_map_stride) { - DRM_ERROR("Cube map stride set twice\n"); + DRM_DEBUG("Cube map stride set twice\n"); goto fail; } cube_map_stride = p3 & VC4_TEX_P2_CMST_MASK; } if (!cube_map_stride) { - DRM_ERROR("Cube map stride not set\n"); + DRM_DEBUG("Cube map stride not set\n"); goto fail; } } @@ -660,7 +660,7 @@ reloc_tex(struct vc4_exec_info *exec, case VC4_TEXTURE_TYPE_RGBA64: case VC4_TEXTURE_TYPE_YUV422R: default: - DRM_ERROR("Texture format %d unsupported\n", type); + DRM_DEBUG("Texture format %d unsupported\n", type); goto fail; } utile_w = utile_width(cpp); @@ -713,7 +713,7 @@ reloc_tex(struct vc4_exec_info *exec, level_size = aligned_width * cpp * aligned_height; if (offset < level_size) { - DRM_ERROR("Level %d (%dx%d -> %dx%d) size %db " + DRM_DEBUG("Level %d (%dx%d -> %dx%d) size %db " "overflowed buffer bounds (offset %d)\n", i, level_width, level_height, aligned_width, aligned_height, @@ -764,7 +764,7 @@ validate_gl_shader_rec(struct drm_device *dev, nr_relocs = ARRAY_SIZE(shader_reloc_offsets) + nr_attributes; if (nr_relocs * 4 > exec->shader_rec_size) { - DRM_ERROR("overflowed shader recs reading %d handles " + DRM_DEBUG("overflowed shader recs reading %d handles " "from %d bytes left\n", nr_relocs, exec->shader_rec_size); return -EINVAL; @@ -774,7 +774,7 @@ validate_gl_shader_rec(struct drm_device *dev, exec->shader_rec_size -= nr_relocs * 4; if (packet_size > exec->shader_rec_size) { - DRM_ERROR("overflowed shader recs copying %db packet " + DRM_DEBUG("overflowed shader recs copying %db packet " "from %d bytes left\n", packet_size, exec->shader_rec_size); return -EINVAL; @@ -794,7 +794,7 @@ validate_gl_shader_rec(struct drm_device *dev, for (i = 0; i < shader_reloc_count; i++) { if (src_handles[i] > exec->bo_count) { - DRM_ERROR("Shader handle %d too big\n", src_handles[i]); + DRM_DEBUG("Shader handle %d too big\n", src_handles[i]); return -EINVAL; } @@ -810,13 +810,13 @@ validate_gl_shader_rec(struct drm_device *dev, if (((*(uint16_t *)pkt_u & VC4_SHADER_FLAG_FS_SINGLE_THREAD) == 0) != to_vc4_bo(&bo[0]->base)->validated_shader->is_threaded) { - DRM_ERROR("Thread mode of CL and FS do not match\n"); + DRM_DEBUG("Thread mode of CL and FS do not match\n"); return -EINVAL; } if (to_vc4_bo(&bo[1]->base)->validated_shader->is_threaded || to_vc4_bo(&bo[2]->base)->validated_shader->is_threaded) { - DRM_ERROR("cs and vs cannot be threaded\n"); + DRM_DEBUG("cs and vs cannot be threaded\n"); return -EINVAL; } @@ -831,7 +831,7 @@ validate_gl_shader_rec(struct drm_device *dev, *(uint32_t *)(pkt_v + o) = bo[i]->paddr + src_offset; if (src_offset != 0) { - DRM_ERROR("Shaders must be at offset 0 of " + DRM_DEBUG("Shaders must be at offset 0 of " "the BO.\n"); return -EINVAL; } @@ -842,7 +842,7 @@ validate_gl_shader_rec(struct drm_device *dev, if (validated_shader->uniforms_src_size > exec->uniforms_size) { - DRM_ERROR("Uniforms src buffer overflow\n"); + DRM_DEBUG("Uniforms src buffer overflow\n"); return -EINVAL; } @@ -900,7 +900,7 @@ validate_gl_shader_rec(struct drm_device *dev, if (vbo->base.size < offset || vbo->base.size - offset < attr_size) { - DRM_ERROR("BO offset overflow (%d + %d > %zu)\n", + DRM_DEBUG("BO offset overflow (%d + %d > %zu)\n", offset, attr_size, vbo->base.size); return -EINVAL; } @@ -909,7 +909,7 @@ validate_gl_shader_rec(struct drm_device *dev, max_index = ((vbo->base.size - offset - attr_size) / stride); if (state->max_index > max_index) { - DRM_ERROR("primitives use index %d out of " + DRM_DEBUG("primitives use index %d out of " "supplied %d\n", state->max_index, max_index); return -EINVAL; diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index 0b2df5c..d3f15bf 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c @@ -200,7 +200,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader, uint32_t clamp_reg, clamp_offset; if (sig == QPU_SIG_SMALL_IMM) { - DRM_ERROR("direct TMU read used small immediate\n"); + DRM_DEBUG("direct TMU read used small immediate\n"); return false; } @@ -209,7 +209,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader, */ if (is_mul || QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_ADD) { - DRM_ERROR("direct TMU load wasn't an add\n"); + DRM_DEBUG("direct TMU load wasn't an add\n"); return false; } @@ -220,13 +220,13 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader, */ clamp_reg = raddr_add_a_to_live_reg_index(inst); if (clamp_reg == ~0) { - DRM_ERROR("direct TMU load wasn't clamped\n"); + DRM_DEBUG("direct TMU load wasn't clamped\n"); return false; } clamp_offset = validation_state->live_min_clamp_offsets[clamp_reg]; if (clamp_offset == ~0) { - DRM_ERROR("direct TMU load wasn't clamped\n"); + DRM_DEBUG("direct TMU load wasn't clamped\n"); return false; } @@ -238,7 +238,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader, if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) && !(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF)) { - DRM_ERROR("direct TMU load didn't add to a uniform\n"); + DRM_DEBUG("direct TMU load didn't add to a uniform\n"); return false; } @@ -246,14 +246,14 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader, } else { if (raddr_a == QPU_R_UNIF || (sig != QPU_SIG_SMALL_IMM && raddr_b == QPU_R_UNIF)) { - DRM_ERROR("uniform read in the same instruction as " + DRM_DEBUG("uniform read in the same instruction as " "texture setup.\n"); return false; } } if (validation_state->tmu_write_count[tmu] >= 4) { - DRM_ERROR("TMU%d got too many parameters before dispatch\n", + DRM_DEBUG("TMU%d got too many parameters before dispatch\n", tmu); return false; } @@ -265,7 +265,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader, */ if (!is_direct) { if (validation_state->needs_uniform_address_update) { - DRM_ERROR("Texturing with undefined uniform address\n"); + DRM_DEBUG("Texturing with undefined uniform address\n"); return false; } @@ -336,35 +336,35 @@ validate_uniform_address_write(struct vc4_validated_shader_info *validated_shade case QPU_SIG_LOAD_TMU1: break; default: - DRM_ERROR("uniforms address change must be " + DRM_DEBUG("uniforms address change must be " "normal math\n"); return false; } if (is_mul || QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_ADD) { - DRM_ERROR("Uniform address reset must be an ADD.\n"); + DRM_DEBUG("Uniform address reset must be an ADD.\n"); return false; } if (QPU_GET_FIELD(inst, QPU_COND_ADD) != QPU_COND_ALWAYS) { - DRM_ERROR("Uniform address reset must be unconditional.\n"); + DRM_DEBUG("Uniform address reset must be unconditional.\n"); return false; } if (QPU_GET_FIELD(inst, QPU_PACK) != QPU_PACK_A_NOP && !(inst & QPU_PM)) { - DRM_ERROR("No packing allowed on uniforms reset\n"); + DRM_DEBUG("No packing allowed on uniforms reset\n"); return false; } if (add_lri == -1) { - DRM_ERROR("First argument of uniform address write must be " + DRM_DEBUG("First argument of uniform address write must be " "an immediate value.\n"); return false; } if (validation_state->live_immediates[add_lri] != expected_offset) { - DRM_ERROR("Resetting uniforms with offset %db instead of %db\n", + DRM_DEBUG("Resetting uniforms with offset %db instead of %db\n", validation_state->live_immediates[add_lri], expected_offset); return false; @@ -372,7 +372,7 @@ validate_uniform_address_write(struct vc4_validated_shader_info *validated_shade if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) && !(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF)) { - DRM_ERROR("Second argument of uniform address write must be " + DRM_DEBUG("Second argument of uniform address write must be " "a uniform.\n"); return false; } @@ -417,7 +417,7 @@ check_reg_write(struct vc4_validated_shader_info *validated_shader, switch (waddr) { case QPU_W_UNIFORMS_ADDRESS: if (is_b) { - DRM_ERROR("relative uniforms address change " + DRM_DEBUG("relative uniforms address change " "unsupported\n"); return false; } @@ -452,11 +452,11 @@ check_reg_write(struct vc4_validated_shader_info *validated_shader, /* XXX: I haven't thought about these, so don't support them * for now. */ - DRM_ERROR("Unsupported waddr %d\n", waddr); + DRM_DEBUG("Unsupported waddr %d\n", waddr); return false; case QPU_W_VPM_ADDR: - DRM_ERROR("General VPM DMA unsupported\n"); + DRM_DEBUG("General VPM DMA unsupported\n"); return false; case QPU_W_VPM: @@ -559,7 +559,7 @@ check_instruction_writes(struct vc4_validated_shader_info *validated_shader, bool ok; if (is_tmu_write(waddr_add) && is_tmu_write(waddr_mul)) { - DRM_ERROR("ADD and MUL both set up textures\n"); + DRM_DEBUG("ADD and MUL both set up textures\n"); return false; } @@ -588,7 +588,7 @@ check_branch(uint64_t inst, * there's no need for it. */ if (waddr_add != QPU_W_NOP || waddr_mul != QPU_W_NOP) { - DRM_ERROR("branch instruction at %d wrote a register.\n", + DRM_DEBUG("branch instruction at %d wrote a register.\n", validation_state->ip); return false; } @@ -614,7 +614,7 @@ check_instruction_reads(struct vc4_validated_shader_info *validated_shader, validated_shader->uniforms_size += 4; if (validation_state->needs_uniform_address_update) { - DRM_ERROR("Uniform read with undefined uniform " + DRM_DEBUG("Uniform read with undefined uniform " "address\n"); return false; } @@ -660,19 +660,19 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state) continue; if (ip - last_branch < 4) { - DRM_ERROR("Branch at %d during delay slots\n", ip); + DRM_DEBUG("Branch at %d during delay slots\n", ip); return false; } last_branch = ip; if (inst & QPU_BRANCH_REG) { - DRM_ERROR("branching from register relative " + DRM_DEBUG("branching from register relative " "not supported\n"); return false; } if (!(inst & QPU_BRANCH_REL)) { - DRM_ERROR("relative branching required\n"); + DRM_DEBUG("relative branching required\n"); return false; } @@ -682,13 +682,13 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state) * end of the shader object. */ if (branch_imm % sizeof(inst) != 0) { - DRM_ERROR("branch target not aligned\n"); + DRM_DEBUG("branch target not aligned\n"); return false; } branch_target_ip = after_delay_ip + (branch_imm >> 3); if (branch_target_ip >= validation_state->max_ip) { - DRM_ERROR("Branch at %d outside of shader (ip %d/%d)\n", + DRM_DEBUG("Branch at %d outside of shader (ip %d/%d)\n", ip, branch_target_ip, validation_state->max_ip); return false; @@ -699,7 +699,7 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state) * the shader. */ if (after_delay_ip >= validation_state->max_ip) { - DRM_ERROR("Branch at %d continues past shader end " + DRM_DEBUG("Branch at %d continues past shader end " "(%d/%d)\n", ip, after_delay_ip, validation_state->max_ip); return false; @@ -709,7 +709,7 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state) } if (max_branch_target > validation_state->max_ip - 3) { - DRM_ERROR("Branch landed after QPU_SIG_PROG_END"); + DRM_DEBUG("Branch landed after QPU_SIG_PROG_END"); return false; } @@ -750,7 +750,7 @@ vc4_handle_branch_target(struct vc4_shader_validation_state *validation_state) return true; if (texturing_in_progress(validation_state)) { - DRM_ERROR("Branch target landed during TMU setup\n"); + DRM_DEBUG("Branch target landed during TMU setup\n"); return false; } @@ -837,7 +837,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) case QPU_SIG_LAST_THREAD_SWITCH: if (!check_instruction_writes(validated_shader, &validation_state)) { - DRM_ERROR("Bad write at ip %d\n", ip); + DRM_DEBUG("Bad write at ip %d\n", ip); goto fail; } @@ -855,7 +855,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) validated_shader->is_threaded = true; if (ip < last_thread_switch_ip + 3) { - DRM_ERROR("Thread switch too soon after " + DRM_DEBUG("Thread switch too soon after " "last switch at ip %d\n", ip); goto fail; } @@ -867,7 +867,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) case QPU_SIG_LOAD_IMM: if (!check_instruction_writes(validated_shader, &validation_state)) { - DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip); + DRM_DEBUG("Bad LOAD_IMM write at ip %d\n", ip); goto fail; } break; @@ -878,14 +878,14 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) goto fail; if (ip < last_thread_switch_ip + 3) { - DRM_ERROR("Branch in thread switch at ip %d", + DRM_DEBUG("Branch in thread switch at ip %d", ip); goto fail; } break; default: - DRM_ERROR("Unsupported QPU signal %d at " + DRM_DEBUG("Unsupported QPU signal %d at " "instruction %d\n", sig, ip); goto fail; } @@ -898,7 +898,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) } if (ip == validation_state.max_ip) { - DRM_ERROR("shader failed to terminate before " + DRM_DEBUG("shader failed to terminate before " "shader BO end at %zd\n", shader_obj->base.size); goto fail; @@ -907,7 +907,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) /* Might corrupt other thread */ if (validated_shader->is_threaded && validation_state.all_registers_used) { - DRM_ERROR("Shader uses threading, but uses the upper " + DRM_DEBUG("Shader uses threading, but uses the upper " "half of the registers, too\n"); goto fail; } diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index 1228967..2524ff1 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -190,7 +190,7 @@ static struct drm_gem_object *vgem_gem_create(struct drm_device *dev, return ERR_CAST(obj); ret = drm_gem_handle_create(file, &obj->base, handle); - drm_gem_object_unreference_unlocked(&obj->base); + drm_gem_object_put_unlocked(&obj->base); if (ret) goto err; @@ -245,7 +245,7 @@ static int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev, *offset = drm_vma_node_offset_addr(&obj->vma_node); unref: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ret; } diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c index 3109c83..8fd52f2 100644 --- a/drivers/gpu/drm/vgem/vgem_fence.c +++ b/drivers/gpu/drm/vgem/vgem_fence.c @@ -213,7 +213,7 @@ err_fence: dma_fence_put(fence); } err: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ret; } diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 63d35c7..49a3d8d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -122,7 +122,6 @@ static struct drm_driver driver = { .dumb_create = virtio_gpu_mode_dumb_create, .dumb_map_offset = virtio_gpu_mode_dumb_mmap, - .dumb_destroy = virtio_gpu_mode_dumb_destroy, #if defined(CONFIG_DEBUG_FS) .debugfs_init = virtio_gpu_debugfs_init, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 3a66abb..da2fb58 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -236,9 +236,6 @@ struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); -int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - uint32_t handle); int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset_p); diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c index 046e28b..15d18fd 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fb.c +++ b/drivers/gpu/drm/virtio/virtgpu_fb.c @@ -308,7 +308,7 @@ static int virtio_gpu_fbdev_destroy(struct drm_device *dev, return 0; } -static struct drm_fb_helper_funcs virtio_gpu_fb_helper_funcs = { +static const struct drm_fb_helper_funcs virtio_gpu_fb_helper_funcs = { .fb_probe = virtio_gpufb_create, }; diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index cc025d8..72ad7b1 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -118,13 +118,6 @@ fail: return ret; } -int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - uint32_t handle) -{ - return drm_gem_handle_delete(file_priv, handle); -} - int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset_p) diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index bf66358..c157284 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -343,7 +343,7 @@ void vbox_fbdev_fini(struct drm_device *dev) vbox_bo_unpin(bo); vbox_bo_unreserve(bo); } - drm_gem_object_unreference_unlocked(afb->obj); + drm_gem_object_put_unlocked(afb->obj); afb->obj = NULL; } drm_fb_helper_fini(&fbdev->helper); diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c index d0c6ec7..80bd039 100644 --- a/drivers/staging/vboxvideo/vbox_main.c +++ b/drivers/staging/vboxvideo/vbox_main.c @@ -40,7 +40,7 @@ static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb) struct vbox_framebuffer *vbox_fb = to_vbox_framebuffer(fb); if (vbox_fb->obj) - drm_gem_object_unreference_unlocked(vbox_fb->obj); + drm_gem_object_put_unlocked(vbox_fb->obj); drm_framebuffer_cleanup(fb); kfree(fb); @@ -198,7 +198,7 @@ static struct drm_framebuffer *vbox_user_framebuffer_create( err_free_vbox_fb: kfree(vbox_fb); err_unref_obj: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ERR_PTR(ret); } @@ -472,7 +472,7 @@ int vbox_dumb_create(struct drm_file *file, return ret; ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); if (ret) return ret; @@ -525,7 +525,7 @@ vbox_dumb_mmap_offset(struct drm_file *file, bo = gem_to_vbox_bo(obj); *offset = vbox_bo_mmap_offset(bo); - drm_gem_object_unreference(obj); + drm_gem_object_put(obj); ret = 0; out_unlock: diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index 996da1c..e5b6383 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -812,7 +812,7 @@ out_unmap_bo: out_unreserve_bo: vbox_bo_unreserve(bo); out_unref_obj: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ret; } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 3aa3809..7277783a 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -82,19 +82,10 @@ #include <drm/drm_sysfs.h> #include <drm/drm_vblank.h> #include <drm/drm_irq.h> - +#include <drm/drm_device.h> struct module; -struct drm_device; -struct drm_agp_head; -struct drm_local_map; -struct drm_device_dma; -struct drm_gem_object; -struct drm_master; -struct drm_vblank_crtc; -struct drm_vma_offset_manager; - struct device_node; struct videomode; struct reservation_object; @@ -306,170 +297,6 @@ struct pci_controller; /** - * DRM device structure. This structure represent a complete card that - * may contain multiple heads. - */ -struct drm_device { - struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */ - int if_version; /**< Highest interface version set */ - - /** \name Lifetime Management */ - /*@{ */ - struct kref ref; /**< Object ref-count */ - struct device *dev; /**< Device structure of bus-device */ - struct drm_driver *driver; /**< DRM driver managing the device */ - void *dev_private; /**< DRM driver private data */ - struct drm_minor *control; /**< Control node */ - struct drm_minor *primary; /**< Primary node */ - struct drm_minor *render; /**< Render node */ - bool registered; - - /* currently active master for this device. Protected by master_mutex */ - struct drm_master *master; - - atomic_t unplugged; /**< Flag whether dev is dead */ - struct inode *anon_inode; /**< inode for private address-space */ - char *unique; /**< unique name of the device */ - /*@} */ - - /** \name Locks */ - /*@{ */ - struct mutex struct_mutex; /**< For others */ - struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */ - /*@} */ - - /** \name Usage Counters */ - /*@{ */ - int open_count; /**< Outstanding files open, protected by drm_global_mutex. */ - spinlock_t buf_lock; /**< For drm_device::buf_use and a few other things. */ - int buf_use; /**< Buffers in use -- cannot alloc */ - atomic_t buf_alloc; /**< Buffer allocation in progress */ - /*@} */ - - struct mutex filelist_mutex; - struct list_head filelist; - - /** \name Memory management */ - /*@{ */ - struct list_head maplist; /**< Linked list of regions */ - struct drm_open_hash map_hash; /**< User token hash table for maps */ - - /** \name Context handle management */ - /*@{ */ - struct list_head ctxlist; /**< Linked list of context handles */ - struct mutex ctxlist_mutex; /**< For ctxlist */ - - struct idr ctx_idr; - - struct list_head vmalist; /**< List of vmas (for debugging) */ - - /*@} */ - - /** \name DMA support */ - /*@{ */ - struct drm_device_dma *dma; /**< Optional pointer for DMA support */ - /*@} */ - - /** \name Context support */ - /*@{ */ - - __volatile__ long context_flag; /**< Context swapping flag */ - int last_context; /**< Last current context */ - /*@} */ - - /** - * @irq_enabled: - * - * Indicates that interrupt handling is enabled, specifically vblank - * handling. Drivers which don't use drm_irq_install() need to set this - * to true manually. - */ - bool irq_enabled; - int irq; - - /** - * @vblank_disable_immediate: - * - * If true, vblank interrupt will be disabled immediately when the - * refcount drops to zero, as opposed to via the vblank disable - * timer. - * - * This can be set to true it the hardware has a working vblank counter - * with high-precision timestamping (otherwise there are races) and the - * driver uses drm_crtc_vblank_on() and drm_crtc_vblank_off() - * appropriately. See also @max_vblank_count and - * &drm_crtc_funcs.get_vblank_counter. - */ - bool vblank_disable_immediate; - - /** - * @vblank: - * - * Array of vblank tracking structures, one per &struct drm_crtc. For - * historical reasons (vblank support predates kernel modesetting) this - * is free-standing and not part of &struct drm_crtc itself. It must be - * initialized explicitly by calling drm_vblank_init(). - */ - struct drm_vblank_crtc *vblank; - - spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ - spinlock_t vbl_lock; - - /** - * @max_vblank_count: - * - * Maximum value of the vblank registers. This value +1 will result in a - * wrap-around of the vblank register. It is used by the vblank core to - * handle wrap-arounds. - * - * If set to zero the vblank core will try to guess the elapsed vblanks - * between times when the vblank interrupt is disabled through - * high-precision timestamps. That approach is suffering from small - * races and imprecision over longer time periods, hence exposing a - * hardware vblank counter is always recommended. - * - * If non-zeor, &drm_crtc_funcs.get_vblank_counter must be set. - */ - u32 max_vblank_count; /**< size of vblank counter register */ - - /** - * List of events - */ - struct list_head vblank_event_list; - spinlock_t event_lock; - - /*@} */ - - struct drm_agp_head *agp; /**< AGP data */ - - struct pci_dev *pdev; /**< PCI device structure */ -#ifdef __alpha__ - struct pci_controller *hose; -#endif - - struct drm_sg_mem *sg; /**< Scatter gather memory */ - unsigned int num_crtcs; /**< Number of CRTCs on this device */ - - struct { - int context; - struct drm_hw_lock *lock; - } sigdata; - - struct drm_local_map *agp_buffer_map; - unsigned int agp_buffer_token; - - struct drm_mode_config mode_config; /**< Current mode config */ - - /** \name GEM information */ - /*@{ */ - struct mutex object_name_lock; - struct idr object_name_idr; - struct drm_vma_offset_manager *vma_offset_manager; - /*@} */ - int switch_power_state; -}; - -/** * drm_drv_uses_atomic_modeset - check if the driver implements * atomic_commit() * @dev: DRM device @@ -493,19 +320,6 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, return ((dev->driver->driver_features & feature) ? 1 : 0); } -static inline void drm_device_set_unplugged(struct drm_device *dev) -{ - smp_wmb(); - atomic_set(&dev->unplugged, 1); -} - -static inline int drm_device_is_unplugged(struct drm_device *dev) -{ - int ret = atomic_read(&dev->unplugged); - smp_rmb(); - return ret; -} - /******************************************************************/ /** \name Internal function definitions */ /*@{*/ diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h new file mode 100644 index 0000000..e21af87 --- /dev/null +++ b/include/drm/drm_device.h @@ -0,0 +1,190 @@ +#ifndef _DRM_DEVICE_H_ +#define _DRM_DEVICE_H_ + +#include <linux/list.h> +#include <linux/kref.h> +#include <linux/mutex.h> +#include <linux/idr.h> + +#include <drm/drm_hashtab.h> +#include <drm/drm_mode_config.h> + +struct drm_driver; +struct drm_minor; +struct drm_master; +struct drm_device_dma; +struct drm_vblank_crtc; +struct drm_sg_mem; +struct drm_local_map; +struct drm_vma_offset_manager; + +struct inode; + +struct pci_dev; +struct pci_controller; + +/** + * DRM device structure. This structure represent a complete card that + * may contain multiple heads. + */ +struct drm_device { + struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */ + int if_version; /**< Highest interface version set */ + + /** \name Lifetime Management */ + /*@{ */ + struct kref ref; /**< Object ref-count */ + struct device *dev; /**< Device structure of bus-device */ + struct drm_driver *driver; /**< DRM driver managing the device */ + void *dev_private; /**< DRM driver private data */ + struct drm_minor *control; /**< Control node */ + struct drm_minor *primary; /**< Primary node */ + struct drm_minor *render; /**< Render node */ + bool registered; + + /* currently active master for this device. Protected by master_mutex */ + struct drm_master *master; + + atomic_t unplugged; /**< Flag whether dev is dead */ + struct inode *anon_inode; /**< inode for private address-space */ + char *unique; /**< unique name of the device */ + /*@} */ + + /** \name Locks */ + /*@{ */ + struct mutex struct_mutex; /**< For others */ + struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */ + /*@} */ + + /** \name Usage Counters */ + /*@{ */ + int open_count; /**< Outstanding files open, protected by drm_global_mutex. */ + spinlock_t buf_lock; /**< For drm_device::buf_use and a few other things. */ + int buf_use; /**< Buffers in use -- cannot alloc */ + atomic_t buf_alloc; /**< Buffer allocation in progress */ + /*@} */ + + struct mutex filelist_mutex; + struct list_head filelist; + + /** \name Memory management */ + /*@{ */ + struct list_head maplist; /**< Linked list of regions */ + struct drm_open_hash map_hash; /**< User token hash table for maps */ + + /** \name Context handle management */ + /*@{ */ + struct list_head ctxlist; /**< Linked list of context handles */ + struct mutex ctxlist_mutex; /**< For ctxlist */ + + struct idr ctx_idr; + + struct list_head vmalist; /**< List of vmas (for debugging) */ + + /*@} */ + + /** \name DMA support */ + /*@{ */ + struct drm_device_dma *dma; /**< Optional pointer for DMA support */ + /*@} */ + + /** \name Context support */ + /*@{ */ + + __volatile__ long context_flag; /**< Context swapping flag */ + int last_context; /**< Last current context */ + /*@} */ + + /** + * @irq_enabled: + * + * Indicates that interrupt handling is enabled, specifically vblank + * handling. Drivers which don't use drm_irq_install() need to set this + * to true manually. + */ + bool irq_enabled; + int irq; + + /** + * @vblank_disable_immediate: + * + * If true, vblank interrupt will be disabled immediately when the + * refcount drops to zero, as opposed to via the vblank disable + * timer. + * + * This can be set to true it the hardware has a working vblank counter + * with high-precision timestamping (otherwise there are races) and the + * driver uses drm_crtc_vblank_on() and drm_crtc_vblank_off() + * appropriately. See also @max_vblank_count and + * &drm_crtc_funcs.get_vblank_counter. + */ + bool vblank_disable_immediate; + + /** + * @vblank: + * + * Array of vblank tracking structures, one per &struct drm_crtc. For + * historical reasons (vblank support predates kernel modesetting) this + * is free-standing and not part of &struct drm_crtc itself. It must be + * initialized explicitly by calling drm_vblank_init(). + */ + struct drm_vblank_crtc *vblank; + + spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ + spinlock_t vbl_lock; + + /** + * @max_vblank_count: + * + * Maximum value of the vblank registers. This value +1 will result in a + * wrap-around of the vblank register. It is used by the vblank core to + * handle wrap-arounds. + * + * If set to zero the vblank core will try to guess the elapsed vblanks + * between times when the vblank interrupt is disabled through + * high-precision timestamps. That approach is suffering from small + * races and imprecision over longer time periods, hence exposing a + * hardware vblank counter is always recommended. + * + * If non-zeor, &drm_crtc_funcs.get_vblank_counter must be set. + */ + u32 max_vblank_count; /**< size of vblank counter register */ + + /** + * List of events + */ + struct list_head vblank_event_list; + spinlock_t event_lock; + + /*@} */ + + struct drm_agp_head *agp; /**< AGP data */ + + struct pci_dev *pdev; /**< PCI device structure */ +#ifdef __alpha__ + struct pci_controller *hose; +#endif + + struct drm_sg_mem *sg; /**< Scatter gather memory */ + unsigned int num_crtcs; /**< Number of CRTCs on this device */ + + struct { + int context; + struct drm_hw_lock *lock; + } sigdata; + + struct drm_local_map *agp_buffer_map; + unsigned int agp_buffer_token; + + struct drm_mode_config mode_config; /**< Current mode config */ + + /** \name GEM information */ + /*@{ */ + struct mutex object_name_lock; + struct idr object_name_idr; + struct drm_vma_offset_manager *vma_offset_manager; + /*@} */ + int switch_power_state; +}; + +#endif diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 505c913..71bbaae 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -30,7 +30,8 @@ #include <linux/list.h> #include <linux/irqreturn.h> -struct drm_device; +#include <drm/drm_device.h> + struct drm_file; struct drm_gem_object; struct drm_master; @@ -613,7 +614,24 @@ void drm_dev_unregister(struct drm_device *dev); void drm_dev_ref(struct drm_device *dev); void drm_dev_unref(struct drm_device *dev); void drm_put_dev(struct drm_device *dev); -void drm_unplug_dev(struct drm_device *dev); +void drm_dev_unplug(struct drm_device *dev); + +/** + * drm_dev_is_unplugged - is a DRM device unplugged + * @dev: DRM device + * + * This function can be called to check whether a hotpluggable is unplugged. + * Unplugging itself is singalled through drm_dev_unplug(). If a device is + * unplugged, these two functions guarantee that any store before calling + * drm_dev_unplug() is visible to callers of this function after it completes + */ +static inline int drm_dev_is_unplugged(struct drm_device *dev) +{ + int ret = atomic_read(&dev->unplugged); + smp_rmb(); + return ret; +} + int drm_dev_set_unique(struct drm_device *dev, const char *name); diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index b42529e..58a739b 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -73,11 +73,6 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, struct drm_device *drm, struct drm_mode_create_dumb *args); -/* map memory region for DRM framebuffer to user space */ -int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *drm, u32 handle, - u64 *offset); - /* set vm_flags and we can change the VM attribute to other one at here */ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma); diff --git a/include/drm/tinydrm/tinydrm-helpers.h b/include/drm/tinydrm/tinydrm-helpers.h index a6c387f..d554ded 100644 --- a/include/drm/tinydrm/tinydrm-helpers.h +++ b/include/drm/tinydrm/tinydrm-helpers.h @@ -43,7 +43,8 @@ void tinydrm_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb, void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_clip_rect *clip, bool swap); -int tinydrm_xrgb8888_to_gray8(u8 *dst, struct drm_framebuffer *fb); +void tinydrm_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb, + struct drm_clip_rect *clip); struct backlight_device *tinydrm_of_find_backlight(struct device *dev); int tinydrm_enable_backlight(struct backlight_device *backlight); diff --git a/include/linux/reservation.h b/include/linux/reservation.h index 156cfd3..21fc84d 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h @@ -254,6 +254,9 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj, unsigned *pshared_count, struct dma_fence ***pshared); +int reservation_object_copy_fences(struct reservation_object *dst, + struct reservation_object *src); + long reservation_object_wait_timeout_rcu(struct reservation_object *obj, bool wait_all, bool intr, unsigned long timeout); diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h index 551628e..afae870 100644 --- a/include/uapi/drm/vc4_drm.h +++ b/include/uapi/drm/vc4_drm.h @@ -155,6 +155,16 @@ struct drm_vc4_submit_cl { __u32 pad:24; #define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0) +/* By default, the kernel gets to choose the order that the tiles are + * rendered in. If this is set, then the tiles will be rendered in a + * raster order, with the right-to-left vs left-to-right and + * top-to-bottom vs bottom-to-top dictated by + * VC4_SUBMIT_CL_RCL_ORDER_INCREASING_*. This allows overlapping + * blits to be implemented using the 3D engine. + */ +#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1) +#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2) +#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3) __u32 flags; /* Returned value of the seqno of this render job (for the @@ -294,6 +304,7 @@ struct drm_vc4_get_hang_state { #define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3 #define DRM_VC4_PARAM_SUPPORTS_ETC1 4 #define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5 +#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6 struct drm_vc4_get_param { __u32 param; |