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
  ...
This commit is contained in:
Dave Airlie 2017-08-17 07:33:41 +10:00
commit 3154b13371
88 changed files with 1059 additions and 628 deletions

View File

@ -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>;
};

View File

@ -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/

View File

@ -195,8 +195,7 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
if (old)
kfree_rcu(old, rcu);
if (old_fence)
dma_fence_put(old_fence);
dma_fence_put(old_fence);
}
/**
@ -258,11 +257,70 @@ 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
@ -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 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
}
}
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)) {

View File

@ -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,

View File

@ -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,
};

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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,
};
/* ---------------------------------------------------------------------- */

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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 = {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -47,36 +47,6 @@ int psb_gem_get_aperture(struct drm_device *dev, void *data,
return -EINVAL;
}
/**
* 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

View File

@ -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,

View File

@ -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 */

View File

@ -157,7 +157,7 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
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 = {

View File

@ -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;

View File

@ -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,

View File

@ -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);
}

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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 = {

View File

@ -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);

View File

@ -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;
}

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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)

View File

@ -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,

View File

@ -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,

View File

@ -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),

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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;
return;
if (import_attach) {
ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
DMA_FROM_DEVICE);
if (ret)
goto err_free;
}
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);

View File

@ -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;

View File

@ -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);

View File

@ -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");

View File

@ -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;
}

View File

@ -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);
}
/*

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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:

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -213,7 +213,7 @@ int vgem_fence_attach_ioctl(struct drm_device *dev,
dma_fence_put(fence);
}
err:
drm_gem_object_unreference_unlocked(obj);
drm_gem_object_put_unlocked(obj);
return ret;
}

View File

@ -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,

View File

@ -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);

View File

@ -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,
};

View File

@ -118,13 +118,6 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
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)

View File

@ -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);

View File

@ -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:

View File

@ -812,7 +812,7 @@ static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
out_unreserve_bo:
vbox_bo_unreserve(bo);
out_unref_obj:
drm_gem_object_unreference_unlocked(obj);
drm_gem_object_put_unlocked(obj);
return ret;
}

View File

@ -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;
@ -305,170 +296,6 @@ struct pci_controller;
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
/**
* 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()
@ -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 */
/*@{*/

190
include/drm/drm_device.h Normal file
View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;