diff options
Diffstat (limited to 'drivers')
37 files changed, 669 insertions, 328 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 7f3be3506057..1fafc2f8e8f9 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -10,7 +10,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ | |||
10 | drm_scatter.o drm_pci.o \ | 10 | drm_scatter.o drm_pci.o \ |
11 | drm_sysfs.o drm_hashtab.o drm_mm.o \ | 11 | drm_sysfs.o drm_hashtab.o drm_mm.o \ |
12 | drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \ | 12 | drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \ |
13 | drm_info.o drm_encoder_slave.o \ | 13 | drm_encoder_slave.o \ |
14 | drm_trace_points.o drm_prime.o \ | 14 | drm_trace_points.o drm_prime.o \ |
15 | drm_rect.o drm_vma_manager.o drm_flip_work.o \ | 15 | drm_rect.o drm_vma_manager.o drm_flip_work.o \ |
16 | drm_modeset_lock.o drm_atomic.o drm_bridge.o \ | 16 | drm_modeset_lock.o drm_atomic.o drm_bridge.o \ |
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 2af847ebca34..206a76abf771 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c | |||
@@ -190,7 +190,7 @@ err_unload: | |||
190 | arcpgu_unload(drm); | 190 | arcpgu_unload(drm); |
191 | 191 | ||
192 | err_unref: | 192 | err_unref: |
193 | drm_dev_unref(drm); | 193 | drm_dev_put(drm); |
194 | 194 | ||
195 | return ret; | 195 | return ret; |
196 | } | 196 | } |
@@ -201,7 +201,7 @@ static int arcpgu_remove(struct platform_device *pdev) | |||
201 | 201 | ||
202 | drm_dev_unregister(drm); | 202 | drm_dev_unregister(drm); |
203 | arcpgu_unload(drm); | 203 | arcpgu_unload(drm); |
204 | drm_dev_unref(drm); | 204 | drm_dev_put(drm); |
205 | 205 | ||
206 | return 0; | 206 | return 0; |
207 | } | 207 | } |
diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c index ee6b98efa9c2..afd491018bfc 100644 --- a/drivers/gpu/drm/bridge/tc358764.c +++ b/drivers/gpu/drm/bridge/tc358764.c | |||
@@ -379,7 +379,7 @@ static void tc358764_detach(struct drm_bridge *bridge) | |||
379 | drm_fb_helper_remove_one_connector(drm->fb_helper, &ctx->connector); | 379 | drm_fb_helper_remove_one_connector(drm->fb_helper, &ctx->connector); |
380 | drm_panel_detach(ctx->panel); | 380 | drm_panel_detach(ctx->panel); |
381 | ctx->panel = NULL; | 381 | ctx->panel = NULL; |
382 | drm_connector_unreference(&ctx->connector); | 382 | drm_connector_put(&ctx->connector); |
383 | } | 383 | } |
384 | 384 | ||
385 | static const struct drm_bridge_funcs tc358764_bridge_funcs = { | 385 | static const struct drm_bridge_funcs tc358764_bridge_funcs = { |
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index fa95f9974f6d..bc9fc9665614 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
@@ -1460,6 +1460,9 @@ void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev, | |||
1460 | DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", | 1460 | DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", |
1461 | crtc->base.id, crtc->name); | 1461 | crtc->base.id, crtc->name); |
1462 | } | 1462 | } |
1463 | |||
1464 | if (old_state->fake_commit) | ||
1465 | complete_all(&old_state->fake_commit->flip_done); | ||
1463 | } | 1466 | } |
1464 | EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done); | 1467 | EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done); |
1465 | 1468 | ||
@@ -2217,8 +2220,10 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state) | |||
2217 | spin_unlock(&crtc->commit_lock); | 2220 | spin_unlock(&crtc->commit_lock); |
2218 | } | 2221 | } |
2219 | 2222 | ||
2220 | if (old_state->fake_commit) | 2223 | if (old_state->fake_commit) { |
2221 | complete_all(&old_state->fake_commit->cleanup_done); | 2224 | complete_all(&old_state->fake_commit->cleanup_done); |
2225 | WARN_ON(!try_wait_for_completion(&old_state->fake_commit->hw_done)); | ||
2226 | } | ||
2222 | } | 2227 | } |
2223 | EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done); | 2228 | EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done); |
2224 | 2229 | ||
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 373bd4c2b698..f8468eae0503 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <drm/drm_debugfs.h> | 32 | #include <drm/drm_debugfs.h> |
33 | #include <drm/drm_edid.h> | 33 | #include <drm/drm_edid.h> |
34 | #include <drm/drm_atomic.h> | 34 | #include <drm/drm_atomic.h> |
35 | #include <drm/drm_auth.h> | ||
36 | #include <drm/drm_gem.h> | ||
35 | #include <drm/drmP.h> | 37 | #include <drm/drmP.h> |
36 | 38 | ||
37 | #include "drm_internal.h" | 39 | #include "drm_internal.h" |
@@ -43,6 +45,93 @@ | |||
43 | * Initialization, etc. | 45 | * Initialization, etc. |
44 | **************************************************/ | 46 | **************************************************/ |
45 | 47 | ||
48 | static int drm_name_info(struct seq_file *m, void *data) | ||
49 | { | ||
50 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
51 | struct drm_minor *minor = node->minor; | ||
52 | struct drm_device *dev = minor->dev; | ||
53 | struct drm_master *master; | ||
54 | |||
55 | mutex_lock(&dev->master_mutex); | ||
56 | master = dev->master; | ||
57 | seq_printf(m, "%s", dev->driver->name); | ||
58 | if (dev->dev) | ||
59 | seq_printf(m, " dev=%s", dev_name(dev->dev)); | ||
60 | if (master && master->unique) | ||
61 | seq_printf(m, " master=%s", master->unique); | ||
62 | if (dev->unique) | ||
63 | seq_printf(m, " unique=%s", dev->unique); | ||
64 | seq_printf(m, "\n"); | ||
65 | mutex_unlock(&dev->master_mutex); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int drm_clients_info(struct seq_file *m, void *data) | ||
71 | { | ||
72 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
73 | struct drm_device *dev = node->minor->dev; | ||
74 | struct drm_file *priv; | ||
75 | kuid_t uid; | ||
76 | |||
77 | seq_printf(m, | ||
78 | "%20s %5s %3s master a %5s %10s\n", | ||
79 | "command", | ||
80 | "pid", | ||
81 | "dev", | ||
82 | "uid", | ||
83 | "magic"); | ||
84 | |||
85 | /* dev->filelist is sorted youngest first, but we want to present | ||
86 | * oldest first (i.e. kernel, servers, clients), so walk backwardss. | ||
87 | */ | ||
88 | mutex_lock(&dev->filelist_mutex); | ||
89 | list_for_each_entry_reverse(priv, &dev->filelist, lhead) { | ||
90 | struct task_struct *task; | ||
91 | |||
92 | rcu_read_lock(); /* locks pid_task()->comm */ | ||
93 | task = pid_task(priv->pid, PIDTYPE_PID); | ||
94 | uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID; | ||
95 | seq_printf(m, "%20s %5d %3d %c %c %5d %10u\n", | ||
96 | task ? task->comm : "<unknown>", | ||
97 | pid_vnr(priv->pid), | ||
98 | priv->minor->index, | ||
99 | drm_is_current_master(priv) ? 'y' : 'n', | ||
100 | priv->authenticated ? 'y' : 'n', | ||
101 | from_kuid_munged(seq_user_ns(m), uid), | ||
102 | priv->magic); | ||
103 | rcu_read_unlock(); | ||
104 | } | ||
105 | mutex_unlock(&dev->filelist_mutex); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int drm_gem_one_name_info(int id, void *ptr, void *data) | ||
110 | { | ||
111 | struct drm_gem_object *obj = ptr; | ||
112 | struct seq_file *m = data; | ||
113 | |||
114 | seq_printf(m, "%6d %8zd %7d %8d\n", | ||
115 | obj->name, obj->size, | ||
116 | obj->handle_count, | ||
117 | kref_read(&obj->refcount)); | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static int drm_gem_name_info(struct seq_file *m, void *data) | ||
122 | { | ||
123 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
124 | struct drm_device *dev = node->minor->dev; | ||
125 | |||
126 | seq_printf(m, " name size handles refcount\n"); | ||
127 | |||
128 | mutex_lock(&dev->object_name_lock); | ||
129 | idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m); | ||
130 | mutex_unlock(&dev->object_name_lock); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
46 | static const struct drm_info_list drm_debugfs_list[] = { | 135 | static const struct drm_info_list drm_debugfs_list[] = { |
47 | {"name", drm_name_info, 0}, | 136 | {"name", drm_name_info, 0}, |
48 | {"clients", drm_clients_info, 0}, | 137 | {"clients", drm_clients_info, 0}, |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index e2ffecd5e453..12e5e2be7890 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -704,19 +704,6 @@ void drm_dev_put(struct drm_device *dev) | |||
704 | } | 704 | } |
705 | EXPORT_SYMBOL(drm_dev_put); | 705 | EXPORT_SYMBOL(drm_dev_put); |
706 | 706 | ||
707 | /** | ||
708 | * drm_dev_unref - Drop reference of a DRM device | ||
709 | * @dev: device to drop reference of or NULL | ||
710 | * | ||
711 | * This is a compatibility alias for drm_dev_put() and should not be used by new | ||
712 | * code. | ||
713 | */ | ||
714 | void drm_dev_unref(struct drm_device *dev) | ||
715 | { | ||
716 | drm_dev_put(dev); | ||
717 | } | ||
718 | EXPORT_SYMBOL(drm_dev_unref); | ||
719 | |||
720 | static int create_compat_control_link(struct drm_device *dev) | 707 | static int create_compat_control_link(struct drm_device *dev) |
721 | { | 708 | { |
722 | struct drm_minor *minor; | 709 | struct drm_minor *minor; |
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c deleted file mode 100644 index 6b68e9088436..000000000000 --- a/drivers/gpu/drm/drm_info.c +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /** | ||
2 | * \file drm_info.c | ||
3 | * DRM info file implementations | ||
4 | * | ||
5 | * \author Ben Gamari <bgamari@gmail.com> | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * Created: Sun Dec 21 13:09:50 2008 by bgamari@gmail.com | ||
10 | * | ||
11 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | ||
12 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | ||
13 | * Copyright 2008 Ben Gamari <bgamari@gmail.com> | ||
14 | * All Rights Reserved. | ||
15 | * | ||
16 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
17 | * copy of this software and associated documentation files (the "Software"), | ||
18 | * to deal in the Software without restriction, including without limitation | ||
19 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
20 | * and/or sell copies of the Software, and to permit persons to whom the | ||
21 | * Software is furnished to do so, subject to the following conditions: | ||
22 | * | ||
23 | * The above copyright notice and this permission notice (including the next | ||
24 | * paragraph) shall be included in all copies or substantial portions of the | ||
25 | * Software. | ||
26 | * | ||
27 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
28 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
29 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
30 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
31 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
32 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
33 | * OTHER DEALINGS IN THE SOFTWARE. | ||
34 | */ | ||
35 | |||
36 | #include <linux/seq_file.h> | ||
37 | #include <drm/drmP.h> | ||
38 | #include <drm/drm_gem.h> | ||
39 | |||
40 | #include "drm_internal.h" | ||
41 | #include "drm_legacy.h" | ||
42 | |||
43 | /** | ||
44 | * Called when "/proc/dri/.../name" is read. | ||
45 | * | ||
46 | * Prints the device name together with the bus id if available. | ||
47 | */ | ||
48 | int drm_name_info(struct seq_file *m, void *data) | ||
49 | { | ||
50 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
51 | struct drm_minor *minor = node->minor; | ||
52 | struct drm_device *dev = minor->dev; | ||
53 | struct drm_master *master; | ||
54 | |||
55 | mutex_lock(&dev->master_mutex); | ||
56 | master = dev->master; | ||
57 | seq_printf(m, "%s", dev->driver->name); | ||
58 | if (dev->dev) | ||
59 | seq_printf(m, " dev=%s", dev_name(dev->dev)); | ||
60 | if (master && master->unique) | ||
61 | seq_printf(m, " master=%s", master->unique); | ||
62 | if (dev->unique) | ||
63 | seq_printf(m, " unique=%s", dev->unique); | ||
64 | seq_printf(m, "\n"); | ||
65 | mutex_unlock(&dev->master_mutex); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * Called when "/proc/dri/.../clients" is read. | ||
72 | * | ||
73 | */ | ||
74 | int drm_clients_info(struct seq_file *m, void *data) | ||
75 | { | ||
76 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
77 | struct drm_device *dev = node->minor->dev; | ||
78 | struct drm_file *priv; | ||
79 | kuid_t uid; | ||
80 | |||
81 | seq_printf(m, | ||
82 | "%20s %5s %3s master a %5s %10s\n", | ||
83 | "command", | ||
84 | "pid", | ||
85 | "dev", | ||
86 | "uid", | ||
87 | "magic"); | ||
88 | |||
89 | /* dev->filelist is sorted youngest first, but we want to present | ||
90 | * oldest first (i.e. kernel, servers, clients), so walk backwardss. | ||
91 | */ | ||
92 | mutex_lock(&dev->filelist_mutex); | ||
93 | list_for_each_entry_reverse(priv, &dev->filelist, lhead) { | ||
94 | struct task_struct *task; | ||
95 | |||
96 | rcu_read_lock(); /* locks pid_task()->comm */ | ||
97 | task = pid_task(priv->pid, PIDTYPE_PID); | ||
98 | uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID; | ||
99 | seq_printf(m, "%20s %5d %3d %c %c %5d %10u\n", | ||
100 | task ? task->comm : "<unknown>", | ||
101 | pid_vnr(priv->pid), | ||
102 | priv->minor->index, | ||
103 | drm_is_current_master(priv) ? 'y' : 'n', | ||
104 | priv->authenticated ? 'y' : 'n', | ||
105 | from_kuid_munged(seq_user_ns(m), uid), | ||
106 | priv->magic); | ||
107 | rcu_read_unlock(); | ||
108 | } | ||
109 | mutex_unlock(&dev->filelist_mutex); | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int drm_gem_one_name_info(int id, void *ptr, void *data) | ||
114 | { | ||
115 | struct drm_gem_object *obj = ptr; | ||
116 | struct seq_file *m = data; | ||
117 | |||
118 | seq_printf(m, "%6d %8zd %7d %8d\n", | ||
119 | obj->name, obj->size, | ||
120 | obj->handle_count, | ||
121 | kref_read(&obj->refcount)); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | int drm_gem_name_info(struct seq_file *m, void *data) | ||
126 | { | ||
127 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
128 | struct drm_device *dev = node->minor->dev; | ||
129 | |||
130 | seq_printf(m, " name size handles refcount\n"); | ||
131 | |||
132 | mutex_lock(&dev->object_name_lock); | ||
133 | idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m); | ||
134 | mutex_unlock(&dev->object_name_lock); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 0c4eb4a9ab31..c7a7d7ce5d1c 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h | |||
@@ -56,11 +56,6 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr | |||
56 | struct drm_minor *drm_minor_acquire(unsigned int minor_id); | 56 | struct drm_minor *drm_minor_acquire(unsigned int minor_id); |
57 | void drm_minor_release(struct drm_minor *minor); | 57 | void drm_minor_release(struct drm_minor *minor); |
58 | 58 | ||
59 | /* drm_info.c */ | ||
60 | int drm_name_info(struct seq_file *m, void *data); | ||
61 | int drm_clients_info(struct seq_file *m, void* data); | ||
62 | int drm_gem_name_info(struct seq_file *m, void *data); | ||
63 | |||
64 | /* drm_vblank.c */ | 59 | /* drm_vblank.c */ |
65 | void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe); | 60 | void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe); |
66 | void drm_vblank_cleanup(struct drm_device *dev); | 61 | void drm_vblank_cleanup(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 5737cb8c6f03..231e3f6d5f41 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c | |||
@@ -663,24 +663,33 @@ EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); | |||
663 | */ | 663 | */ |
664 | int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) | 664 | int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) |
665 | { | 665 | { |
666 | /* Used by drm_gem_mmap() to lookup the GEM object */ | 666 | struct drm_file *priv; |
667 | struct drm_file priv = { | 667 | struct file *fil; |
668 | .minor = obj->dev->primary, | ||
669 | }; | ||
670 | struct file fil = { | ||
671 | .private_data = &priv, | ||
672 | }; | ||
673 | int ret; | 668 | int ret; |
674 | 669 | ||
675 | ret = drm_vma_node_allow(&obj->vma_node, &priv); | 670 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
671 | fil = kzalloc(sizeof(*fil), GFP_KERNEL); | ||
672 | if (!priv || !fil) { | ||
673 | ret = -ENOMEM; | ||
674 | goto out; | ||
675 | } | ||
676 | |||
677 | /* Used by drm_gem_mmap() to lookup the GEM object */ | ||
678 | priv->minor = obj->dev->primary; | ||
679 | fil->private_data = priv; | ||
680 | |||
681 | ret = drm_vma_node_allow(&obj->vma_node, priv); | ||
676 | if (ret) | 682 | if (ret) |
677 | return ret; | 683 | goto out; |
678 | 684 | ||
679 | vma->vm_pgoff += drm_vma_node_start(&obj->vma_node); | 685 | vma->vm_pgoff += drm_vma_node_start(&obj->vma_node); |
680 | 686 | ||
681 | ret = obj->dev->driver->fops->mmap(&fil, vma); | 687 | ret = obj->dev->driver->fops->mmap(fil, vma); |
682 | 688 | ||
683 | drm_vma_node_revoke(&obj->vma_node, &priv); | 689 | drm_vma_node_revoke(&obj->vma_node, priv); |
690 | out: | ||
691 | kfree(priv); | ||
692 | kfree(fil); | ||
684 | 693 | ||
685 | return ret; | 694 | return ret; |
686 | } | 695 | } |
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 83c1f46670bf..52802e6049e0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c | |||
@@ -550,7 +550,7 @@ out_register: | |||
550 | out_bind: | 550 | out_bind: |
551 | kfree(priv); | 551 | kfree(priv); |
552 | out_unref: | 552 | out_unref: |
553 | drm_dev_unref(drm); | 553 | drm_dev_put(drm); |
554 | 554 | ||
555 | return ret; | 555 | return ret; |
556 | } | 556 | } |
@@ -567,7 +567,7 @@ static void etnaviv_unbind(struct device *dev) | |||
567 | drm->dev_private = NULL; | 567 | drm->dev_private = NULL; |
568 | kfree(priv); | 568 | kfree(priv); |
569 | 569 | ||
570 | drm_dev_unref(drm); | 570 | drm_dev_put(drm); |
571 | } | 571 | } |
572 | 572 | ||
573 | static const struct component_master_ops etnaviv_master_ops = { | 573 | static const struct component_master_ops etnaviv_master_ops = { |
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index df7247cd93f9..d8c5cc34e22e 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c | |||
@@ -594,17 +594,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector, | |||
594 | dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__, | 594 | dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__, |
595 | vclk_freq, venc_freq, hdmi_freq); | 595 | vclk_freq, venc_freq, hdmi_freq); |
596 | 596 | ||
597 | /* Finally filter by configurable vclk frequencies for VIC modes */ | 597 | return meson_vclk_vic_supported_freq(vclk_freq); |
598 | switch (vclk_freq) { | ||
599 | case 54000: | ||
600 | case 74250: | ||
601 | case 148500: | ||
602 | case 297000: | ||
603 | case 594000: | ||
604 | return MODE_OK; | ||
605 | } | ||
606 | |||
607 | return MODE_CLOCK_RANGE; | ||
608 | } | 598 | } |
609 | 599 | ||
610 | /* Encoder */ | 600 | /* Encoder */ |
diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c index 9aebc5e4b418..691a9fd16b36 100644 --- a/drivers/gpu/drm/meson/meson_overlay.c +++ b/drivers/gpu/drm/meson/meson_overlay.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <drm/drm_plane_helper.h> | 16 | #include <drm/drm_plane_helper.h> |
17 | #include <drm/drm_gem_cma_helper.h> | 17 | #include <drm/drm_gem_cma_helper.h> |
18 | #include <drm/drm_fb_cma_helper.h> | 18 | #include <drm/drm_fb_cma_helper.h> |
19 | #include <drm/drm_gem_framebuffer_helper.h> | ||
19 | #include <drm/drm_rect.h> | 20 | #include <drm/drm_rect.h> |
20 | 21 | ||
21 | #include "meson_overlay.h" | 22 | #include "meson_overlay.h" |
@@ -532,6 +533,7 @@ static const struct drm_plane_helper_funcs meson_overlay_helper_funcs = { | |||
532 | .atomic_check = meson_overlay_atomic_check, | 533 | .atomic_check = meson_overlay_atomic_check, |
533 | .atomic_disable = meson_overlay_atomic_disable, | 534 | .atomic_disable = meson_overlay_atomic_disable, |
534 | .atomic_update = meson_overlay_atomic_update, | 535 | .atomic_update = meson_overlay_atomic_update, |
536 | .prepare_fb = drm_gem_fb_prepare_fb, | ||
535 | }; | 537 | }; |
536 | 538 | ||
537 | static const struct drm_plane_funcs meson_overlay_funcs = { | 539 | static const struct drm_plane_funcs meson_overlay_funcs = { |
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c index 12a47b4f65a5..8ee2cf9e47cd 100644 --- a/drivers/gpu/drm/meson/meson_plane.c +++ b/drivers/gpu/drm/meson/meson_plane.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <drm/drm_plane_helper.h> | 32 | #include <drm/drm_plane_helper.h> |
33 | #include <drm/drm_gem_cma_helper.h> | 33 | #include <drm/drm_gem_cma_helper.h> |
34 | #include <drm/drm_fb_cma_helper.h> | 34 | #include <drm/drm_fb_cma_helper.h> |
35 | #include <drm/drm_gem_framebuffer_helper.h> | ||
35 | #include <drm/drm_rect.h> | 36 | #include <drm/drm_rect.h> |
36 | 37 | ||
37 | #include "meson_plane.h" | 38 | #include "meson_plane.h" |
@@ -322,6 +323,7 @@ static const struct drm_plane_helper_funcs meson_plane_helper_funcs = { | |||
322 | .atomic_check = meson_plane_atomic_check, | 323 | .atomic_check = meson_plane_atomic_check, |
323 | .atomic_disable = meson_plane_atomic_disable, | 324 | .atomic_disable = meson_plane_atomic_disable, |
324 | .atomic_update = meson_plane_atomic_update, | 325 | .atomic_update = meson_plane_atomic_update, |
326 | .prepare_fb = drm_gem_fb_prepare_fb, | ||
325 | }; | 327 | }; |
326 | 328 | ||
327 | static const struct drm_plane_funcs meson_plane_funcs = { | 329 | static const struct drm_plane_funcs meson_plane_funcs = { |
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index ae5473257f72..f6ba35a405f8 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c | |||
@@ -117,6 +117,8 @@ | |||
117 | #define HDMI_PLL_RESET BIT(28) | 117 | #define HDMI_PLL_RESET BIT(28) |
118 | #define HDMI_PLL_LOCK BIT(31) | 118 | #define HDMI_PLL_LOCK BIT(31) |
119 | 119 | ||
120 | #define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001) | ||
121 | |||
120 | /* VID PLL Dividers */ | 122 | /* VID PLL Dividers */ |
121 | enum { | 123 | enum { |
122 | VID_PLL_DIV_1 = 0, | 124 | VID_PLL_DIV_1 = 0, |
@@ -323,7 +325,7 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv) | |||
323 | enum { | 325 | enum { |
324 | /* PLL O1 O2 O3 VP DV EN TX */ | 326 | /* PLL O1 O2 O3 VP DV EN TX */ |
325 | /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ | 327 | /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ |
326 | MESON_VCLK_HDMI_ENCI_54000 = 1, | 328 | MESON_VCLK_HDMI_ENCI_54000 = 0, |
327 | /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ | 329 | /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ |
328 | MESON_VCLK_HDMI_DDR_54000, | 330 | MESON_VCLK_HDMI_DDR_54000, |
329 | /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ | 331 | /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ |
@@ -339,6 +341,7 @@ enum { | |||
339 | }; | 341 | }; |
340 | 342 | ||
341 | struct meson_vclk_params { | 343 | struct meson_vclk_params { |
344 | unsigned int pixel_freq; | ||
342 | unsigned int pll_base_freq; | 345 | unsigned int pll_base_freq; |
343 | unsigned int pll_od1; | 346 | unsigned int pll_od1; |
344 | unsigned int pll_od2; | 347 | unsigned int pll_od2; |
@@ -347,6 +350,7 @@ struct meson_vclk_params { | |||
347 | unsigned int vclk_div; | 350 | unsigned int vclk_div; |
348 | } params[] = { | 351 | } params[] = { |
349 | [MESON_VCLK_HDMI_ENCI_54000] = { | 352 | [MESON_VCLK_HDMI_ENCI_54000] = { |
353 | .pixel_freq = 54000, | ||
350 | .pll_base_freq = 4320000, | 354 | .pll_base_freq = 4320000, |
351 | .pll_od1 = 4, | 355 | .pll_od1 = 4, |
352 | .pll_od2 = 4, | 356 | .pll_od2 = 4, |
@@ -355,6 +359,7 @@ struct meson_vclk_params { | |||
355 | .vclk_div = 1, | 359 | .vclk_div = 1, |
356 | }, | 360 | }, |
357 | [MESON_VCLK_HDMI_DDR_54000] = { | 361 | [MESON_VCLK_HDMI_DDR_54000] = { |
362 | .pixel_freq = 54000, | ||
358 | .pll_base_freq = 4320000, | 363 | .pll_base_freq = 4320000, |
359 | .pll_od1 = 4, | 364 | .pll_od1 = 4, |
360 | .pll_od2 = 4, | 365 | .pll_od2 = 4, |
@@ -363,6 +368,7 @@ struct meson_vclk_params { | |||
363 | .vclk_div = 1, | 368 | .vclk_div = 1, |
364 | }, | 369 | }, |
365 | [MESON_VCLK_HDMI_DDR_148500] = { | 370 | [MESON_VCLK_HDMI_DDR_148500] = { |
371 | .pixel_freq = 148500, | ||
366 | .pll_base_freq = 2970000, | 372 | .pll_base_freq = 2970000, |
367 | .pll_od1 = 4, | 373 | .pll_od1 = 4, |
368 | .pll_od2 = 1, | 374 | .pll_od2 = 1, |
@@ -371,6 +377,7 @@ struct meson_vclk_params { | |||
371 | .vclk_div = 1, | 377 | .vclk_div = 1, |
372 | }, | 378 | }, |
373 | [MESON_VCLK_HDMI_74250] = { | 379 | [MESON_VCLK_HDMI_74250] = { |
380 | .pixel_freq = 74250, | ||
374 | .pll_base_freq = 2970000, | 381 | .pll_base_freq = 2970000, |
375 | .pll_od1 = 2, | 382 | .pll_od1 = 2, |
376 | .pll_od2 = 2, | 383 | .pll_od2 = 2, |
@@ -379,6 +386,7 @@ struct meson_vclk_params { | |||
379 | .vclk_div = 1, | 386 | .vclk_div = 1, |
380 | }, | 387 | }, |
381 | [MESON_VCLK_HDMI_148500] = { | 388 | [MESON_VCLK_HDMI_148500] = { |
389 | .pixel_freq = 148500, | ||
382 | .pll_base_freq = 2970000, | 390 | .pll_base_freq = 2970000, |
383 | .pll_od1 = 1, | 391 | .pll_od1 = 1, |
384 | .pll_od2 = 2, | 392 | .pll_od2 = 2, |
@@ -387,6 +395,7 @@ struct meson_vclk_params { | |||
387 | .vclk_div = 1, | 395 | .vclk_div = 1, |
388 | }, | 396 | }, |
389 | [MESON_VCLK_HDMI_297000] = { | 397 | [MESON_VCLK_HDMI_297000] = { |
398 | .pixel_freq = 297000, | ||
390 | .pll_base_freq = 2970000, | 399 | .pll_base_freq = 2970000, |
391 | .pll_od1 = 1, | 400 | .pll_od1 = 1, |
392 | .pll_od2 = 1, | 401 | .pll_od2 = 1, |
@@ -395,6 +404,7 @@ struct meson_vclk_params { | |||
395 | .vclk_div = 2, | 404 | .vclk_div = 2, |
396 | }, | 405 | }, |
397 | [MESON_VCLK_HDMI_594000] = { | 406 | [MESON_VCLK_HDMI_594000] = { |
407 | .pixel_freq = 594000, | ||
398 | .pll_base_freq = 5940000, | 408 | .pll_base_freq = 5940000, |
399 | .pll_od1 = 1, | 409 | .pll_od1 = 1, |
400 | .pll_od2 = 1, | 410 | .pll_od2 = 1, |
@@ -402,6 +412,7 @@ struct meson_vclk_params { | |||
402 | .vid_pll_div = VID_PLL_DIV_5, | 412 | .vid_pll_div = VID_PLL_DIV_5, |
403 | .vclk_div = 1, | 413 | .vclk_div = 1, |
404 | }, | 414 | }, |
415 | { /* sentinel */ }, | ||
405 | }; | 416 | }; |
406 | 417 | ||
407 | static inline unsigned int pll_od_to_reg(unsigned int od) | 418 | static inline unsigned int pll_od_to_reg(unsigned int od) |
@@ -626,12 +637,37 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, | |||
626 | pll_freq); | 637 | pll_freq); |
627 | } | 638 | } |
628 | 639 | ||
640 | enum drm_mode_status | ||
641 | meson_vclk_vic_supported_freq(unsigned int freq) | ||
642 | { | ||
643 | int i; | ||
644 | |||
645 | DRM_DEBUG_DRIVER("freq = %d\n", freq); | ||
646 | |||
647 | for (i = 0 ; params[i].pixel_freq ; ++i) { | ||
648 | DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n", | ||
649 | i, params[i].pixel_freq, | ||
650 | FREQ_1000_1001(params[i].pixel_freq)); | ||
651 | /* Match strict frequency */ | ||
652 | if (freq == params[i].pixel_freq) | ||
653 | return MODE_OK; | ||
654 | /* Match 1000/1001 variant */ | ||
655 | if (freq == FREQ_1000_1001(params[i].pixel_freq)) | ||
656 | return MODE_OK; | ||
657 | } | ||
658 | |||
659 | return MODE_CLOCK_RANGE; | ||
660 | } | ||
661 | EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq); | ||
662 | |||
629 | static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, | 663 | static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, |
630 | unsigned int od1, unsigned int od2, unsigned int od3, | 664 | unsigned int od1, unsigned int od2, unsigned int od3, |
631 | unsigned int vid_pll_div, unsigned int vclk_div, | 665 | unsigned int vid_pll_div, unsigned int vclk_div, |
632 | unsigned int hdmi_tx_div, unsigned int venc_div, | 666 | unsigned int hdmi_tx_div, unsigned int venc_div, |
633 | bool hdmi_use_enci) | 667 | bool hdmi_use_enci, bool vic_alternate_clock) |
634 | { | 668 | { |
669 | unsigned int m = 0, frac = 0; | ||
670 | |||
635 | /* Set HDMI-TX sys clock */ | 671 | /* Set HDMI-TX sys clock */ |
636 | regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, | 672 | regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, |
637 | CTS_HDMI_SYS_SEL_MASK, 0); | 673 | CTS_HDMI_SYS_SEL_MASK, 0); |
@@ -646,34 +682,38 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, | |||
646 | } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { | 682 | } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { |
647 | switch (pll_base_freq) { | 683 | switch (pll_base_freq) { |
648 | case 2970000: | 684 | case 2970000: |
649 | meson_hdmi_pll_set_params(priv, 0x3d, 0xe00, | 685 | m = 0x3d; |
650 | od1, od2, od3); | 686 | frac = vic_alternate_clock ? 0xd02 : 0xe00; |
651 | break; | 687 | break; |
652 | case 4320000: | 688 | case 4320000: |
653 | meson_hdmi_pll_set_params(priv, 0x5a, 0, | 689 | m = vic_alternate_clock ? 0x59 : 0x5a; |
654 | od1, od2, od3); | 690 | frac = vic_alternate_clock ? 0xe8f : 0; |
655 | break; | 691 | break; |
656 | case 5940000: | 692 | case 5940000: |
657 | meson_hdmi_pll_set_params(priv, 0x7b, 0xc00, | 693 | m = 0x7b; |
658 | od1, od2, od3); | 694 | frac = vic_alternate_clock ? 0xa05 : 0xc00; |
659 | break; | 695 | break; |
660 | } | 696 | } |
697 | |||
698 | meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); | ||
661 | } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || | 699 | } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || |
662 | meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { | 700 | meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { |
663 | switch (pll_base_freq) { | 701 | switch (pll_base_freq) { |
664 | case 2970000: | 702 | case 2970000: |
665 | meson_hdmi_pll_set_params(priv, 0x7b, 0x300, | 703 | m = 0x7b; |
666 | od1, od2, od3); | 704 | frac = vic_alternate_clock ? 0x281 : 0x300; |
667 | break; | 705 | break; |
668 | case 4320000: | 706 | case 4320000: |
669 | meson_hdmi_pll_set_params(priv, 0xb4, 0, | 707 | m = vic_alternate_clock ? 0xb3 : 0xb4; |
670 | od1, od2, od3); | 708 | frac = vic_alternate_clock ? 0x347 : 0; |
671 | break; | 709 | break; |
672 | case 5940000: | 710 | case 5940000: |
673 | meson_hdmi_pll_set_params(priv, 0xf7, 0x200, | 711 | m = 0xf7; |
674 | od1, od2, od3); | 712 | frac = vic_alternate_clock ? 0x102 : 0x200; |
675 | break; | 713 | break; |
676 | } | 714 | } |
715 | |||
716 | meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); | ||
677 | } | 717 | } |
678 | 718 | ||
679 | /* Setup vid_pll divider */ | 719 | /* Setup vid_pll divider */ |
@@ -826,6 +866,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | |||
826 | unsigned int vclk_freq, unsigned int venc_freq, | 866 | unsigned int vclk_freq, unsigned int venc_freq, |
827 | unsigned int dac_freq, bool hdmi_use_enci) | 867 | unsigned int dac_freq, bool hdmi_use_enci) |
828 | { | 868 | { |
869 | bool vic_alternate_clock = false; | ||
829 | unsigned int freq; | 870 | unsigned int freq; |
830 | unsigned int hdmi_tx_div; | 871 | unsigned int hdmi_tx_div; |
831 | unsigned int venc_div; | 872 | unsigned int venc_div; |
@@ -843,7 +884,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | |||
843 | * - encp encoder | 884 | * - encp encoder |
844 | */ | 885 | */ |
845 | meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0, | 886 | meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0, |
846 | VID_PLL_DIV_5, 2, 1, 1, false); | 887 | VID_PLL_DIV_5, 2, 1, 1, false, false); |
847 | return; | 888 | return; |
848 | } | 889 | } |
849 | 890 | ||
@@ -863,31 +904,35 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | |||
863 | return; | 904 | return; |
864 | } | 905 | } |
865 | 906 | ||
866 | switch (vclk_freq) { | 907 | for (freq = 0 ; params[freq].pixel_freq ; ++freq) { |
867 | case 54000: | 908 | if (vclk_freq == params[freq].pixel_freq || |
868 | if (hdmi_use_enci) | 909 | vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) { |
869 | freq = MESON_VCLK_HDMI_ENCI_54000; | 910 | if (vclk_freq != params[freq].pixel_freq) |
870 | else | 911 | vic_alternate_clock = true; |
871 | freq = MESON_VCLK_HDMI_DDR_54000; | 912 | else |
872 | break; | 913 | vic_alternate_clock = false; |
873 | case 74250: | 914 | |
874 | freq = MESON_VCLK_HDMI_74250; | 915 | if (freq == MESON_VCLK_HDMI_ENCI_54000 && |
875 | break; | 916 | !hdmi_use_enci) |
876 | case 148500: | 917 | continue; |
877 | if (dac_freq != 148500) | 918 | |
878 | freq = MESON_VCLK_HDMI_DDR_148500; | 919 | if (freq == MESON_VCLK_HDMI_DDR_54000 && |
879 | else | 920 | hdmi_use_enci) |
880 | freq = MESON_VCLK_HDMI_148500; | 921 | continue; |
881 | break; | 922 | |
882 | case 297000: | 923 | if (freq == MESON_VCLK_HDMI_DDR_148500 && |
883 | freq = MESON_VCLK_HDMI_297000; | 924 | dac_freq == vclk_freq) |
884 | break; | 925 | continue; |
885 | case 594000: | 926 | |
886 | freq = MESON_VCLK_HDMI_594000; | 927 | if (freq == MESON_VCLK_HDMI_148500 && |
887 | break; | 928 | dac_freq != vclk_freq) |
888 | default: | 929 | continue; |
889 | pr_err("Fatal Error, invalid HDMI vclk freq %d\n", | 930 | break; |
890 | vclk_freq); | 931 | } |
932 | } | ||
933 | |||
934 | if (!params[freq].pixel_freq) { | ||
935 | pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq); | ||
891 | return; | 936 | return; |
892 | } | 937 | } |
893 | 938 | ||
@@ -895,6 +940,6 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | |||
895 | params[freq].pll_od1, params[freq].pll_od2, | 940 | params[freq].pll_od1, params[freq].pll_od2, |
896 | params[freq].pll_od3, params[freq].vid_pll_div, | 941 | params[freq].pll_od3, params[freq].vid_pll_div, |
897 | params[freq].vclk_div, hdmi_tx_div, venc_div, | 942 | params[freq].vclk_div, hdmi_tx_div, venc_div, |
898 | hdmi_use_enci); | 943 | hdmi_use_enci, vic_alternate_clock); |
899 | } | 944 | } |
900 | EXPORT_SYMBOL_GPL(meson_vclk_setup); | 945 | EXPORT_SYMBOL_GPL(meson_vclk_setup); |
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h index 869fa3a3073e..4bd8752da02a 100644 --- a/drivers/gpu/drm/meson/meson_vclk.h +++ b/drivers/gpu/drm/meson/meson_vclk.h | |||
@@ -32,6 +32,8 @@ enum { | |||
32 | 32 | ||
33 | enum drm_mode_status | 33 | enum drm_mode_status |
34 | meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq); | 34 | meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq); |
35 | enum drm_mode_status | ||
36 | meson_vclk_vic_supported_freq(unsigned int freq); | ||
35 | 37 | ||
36 | void meson_vclk_setup(struct meson_drm *priv, unsigned int target, | 38 | void meson_vclk_setup(struct meson_drm *priv, unsigned int target, |
37 | unsigned int vclk_freq, unsigned int venc_freq, | 39 | unsigned int vclk_freq, unsigned int venc_freq, |
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c index acbbad3e322c..e95e0e7a7fa1 100644 --- a/drivers/gpu/drm/meson/meson_venc.c +++ b/drivers/gpu/drm/meson/meson_venc.c | |||
@@ -697,6 +697,132 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { | |||
697 | }, | 697 | }, |
698 | }; | 698 | }; |
699 | 699 | ||
700 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = { | ||
701 | .encp = { | ||
702 | .dvi_settings = 0x1, | ||
703 | .video_mode = 0x4040, | ||
704 | .video_mode_adv = 0x8, | ||
705 | /* video_sync_mode */ | ||
706 | /* video_yc_dly */ | ||
707 | /* video_rgb_ctrl */ | ||
708 | .video_filt_ctrl = 0x1000, | ||
709 | .video_filt_ctrl_present = true, | ||
710 | /* video_ofld_voav_ofst */ | ||
711 | .yfp1_htime = 140, | ||
712 | .yfp2_htime = 140+3840, | ||
713 | .max_pxcnt = 3840+1660-1, | ||
714 | .hspuls_begin = 2156+1920, | ||
715 | .hspuls_end = 44, | ||
716 | .hspuls_switch = 44, | ||
717 | .vspuls_begin = 140, | ||
718 | .vspuls_end = 2059+1920, | ||
719 | .vspuls_bline = 0, | ||
720 | .vspuls_eline = 4, | ||
721 | .havon_begin = 148, | ||
722 | .havon_end = 3987, | ||
723 | .vavon_bline = 89, | ||
724 | .vavon_eline = 2248, | ||
725 | /* eqpuls_begin */ | ||
726 | /* eqpuls_end */ | ||
727 | /* eqpuls_bline */ | ||
728 | /* eqpuls_eline */ | ||
729 | .hso_begin = 44, | ||
730 | .hso_end = 2156+1920, | ||
731 | .vso_begin = 2100+1920, | ||
732 | .vso_end = 2164+1920, | ||
733 | .vso_bline = 51, | ||
734 | .vso_eline = 53, | ||
735 | .vso_eline_present = true, | ||
736 | /* sy_val */ | ||
737 | /* sy2_val */ | ||
738 | .max_lncnt = 2249, | ||
739 | }, | ||
740 | }; | ||
741 | |||
742 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = { | ||
743 | .encp = { | ||
744 | .dvi_settings = 0x1, | ||
745 | .video_mode = 0x4040, | ||
746 | .video_mode_adv = 0x8, | ||
747 | /* video_sync_mode */ | ||
748 | /* video_yc_dly */ | ||
749 | /* video_rgb_ctrl */ | ||
750 | .video_filt_ctrl = 0x1000, | ||
751 | .video_filt_ctrl_present = true, | ||
752 | /* video_ofld_voav_ofst */ | ||
753 | .yfp1_htime = 140, | ||
754 | .yfp2_htime = 140+3840, | ||
755 | .max_pxcnt = 3840+1440-1, | ||
756 | .hspuls_begin = 2156+1920, | ||
757 | .hspuls_end = 44, | ||
758 | .hspuls_switch = 44, | ||
759 | .vspuls_begin = 140, | ||
760 | .vspuls_end = 2059+1920, | ||
761 | .vspuls_bline = 0, | ||
762 | .vspuls_eline = 4, | ||
763 | .havon_begin = 148, | ||
764 | .havon_end = 3987, | ||
765 | .vavon_bline = 89, | ||
766 | .vavon_eline = 2248, | ||
767 | /* eqpuls_begin */ | ||
768 | /* eqpuls_end */ | ||
769 | /* eqpuls_bline */ | ||
770 | /* eqpuls_eline */ | ||
771 | .hso_begin = 44, | ||
772 | .hso_end = 2156+1920, | ||
773 | .vso_begin = 2100+1920, | ||
774 | .vso_end = 2164+1920, | ||
775 | .vso_bline = 51, | ||
776 | .vso_eline = 53, | ||
777 | .vso_eline_present = true, | ||
778 | /* sy_val */ | ||
779 | /* sy2_val */ | ||
780 | .max_lncnt = 2249, | ||
781 | }, | ||
782 | }; | ||
783 | |||
784 | union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = { | ||
785 | .encp = { | ||
786 | .dvi_settings = 0x1, | ||
787 | .video_mode = 0x4040, | ||
788 | .video_mode_adv = 0x8, | ||
789 | /* video_sync_mode */ | ||
790 | /* video_yc_dly */ | ||
791 | /* video_rgb_ctrl */ | ||
792 | .video_filt_ctrl = 0x1000, | ||
793 | .video_filt_ctrl_present = true, | ||
794 | /* video_ofld_voav_ofst */ | ||
795 | .yfp1_htime = 140, | ||
796 | .yfp2_htime = 140+3840, | ||
797 | .max_pxcnt = 3840+560-1, | ||
798 | .hspuls_begin = 2156+1920, | ||
799 | .hspuls_end = 44, | ||
800 | .hspuls_switch = 44, | ||
801 | .vspuls_begin = 140, | ||
802 | .vspuls_end = 2059+1920, | ||
803 | .vspuls_bline = 0, | ||
804 | .vspuls_eline = 4, | ||
805 | .havon_begin = 148, | ||
806 | .havon_end = 3987, | ||
807 | .vavon_bline = 89, | ||
808 | .vavon_eline = 2248, | ||
809 | /* eqpuls_begin */ | ||
810 | /* eqpuls_end */ | ||
811 | /* eqpuls_bline */ | ||
812 | /* eqpuls_eline */ | ||
813 | .hso_begin = 44, | ||
814 | .hso_end = 2156+1920, | ||
815 | .vso_begin = 2100+1920, | ||
816 | .vso_end = 2164+1920, | ||
817 | .vso_bline = 51, | ||
818 | .vso_eline = 53, | ||
819 | .vso_eline_present = true, | ||
820 | /* sy_val */ | ||
821 | /* sy2_val */ | ||
822 | .max_lncnt = 2249, | ||
823 | }, | ||
824 | }; | ||
825 | |||
700 | struct meson_hdmi_venc_vic_mode { | 826 | struct meson_hdmi_venc_vic_mode { |
701 | unsigned int vic; | 827 | unsigned int vic; |
702 | union meson_hdmi_venc_mode *mode; | 828 | union meson_hdmi_venc_mode *mode; |
@@ -717,6 +843,9 @@ struct meson_hdmi_venc_vic_mode { | |||
717 | { 34, &meson_hdmi_encp_mode_1080p30 }, | 843 | { 34, &meson_hdmi_encp_mode_1080p30 }, |
718 | { 31, &meson_hdmi_encp_mode_1080p50 }, | 844 | { 31, &meson_hdmi_encp_mode_1080p50 }, |
719 | { 16, &meson_hdmi_encp_mode_1080p60 }, | 845 | { 16, &meson_hdmi_encp_mode_1080p60 }, |
846 | { 93, &meson_hdmi_encp_mode_2160p24 }, | ||
847 | { 94, &meson_hdmi_encp_mode_2160p25 }, | ||
848 | { 95, &meson_hdmi_encp_mode_2160p30 }, | ||
720 | { 0, NULL}, /* sentinel */ | 849 | { 0, NULL}, /* sentinel */ |
721 | }; | 850 | }; |
722 | 851 | ||
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index 2393e6d16ffd..88ba003979e6 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c | |||
@@ -417,7 +417,7 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
417 | err_unload: | 417 | err_unload: |
418 | mxsfb_unload(drm); | 418 | mxsfb_unload(drm); |
419 | err_free: | 419 | err_free: |
420 | drm_dev_unref(drm); | 420 | drm_dev_put(drm); |
421 | 421 | ||
422 | return ret; | 422 | return ret; |
423 | } | 423 | } |
@@ -428,7 +428,7 @@ static int mxsfb_remove(struct platform_device *pdev) | |||
428 | 428 | ||
429 | drm_dev_unregister(drm); | 429 | drm_dev_unregister(drm); |
430 | mxsfb_unload(drm); | 430 | mxsfb_unload(drm); |
431 | drm_dev_unref(drm); | 431 | drm_dev_put(drm); |
432 | 432 | ||
433 | return 0; | 433 | return 0; |
434 | } | 434 | } |
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index bf49c55b0f2c..9e9255ee59cd 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c | |||
@@ -48,8 +48,12 @@ static const u32 sunxi_rgb2yuv_coef[12] = { | |||
48 | /* | 48 | /* |
49 | * These coefficients are taken from the A33 BSP from Allwinner. | 49 | * These coefficients are taken from the A33 BSP from Allwinner. |
50 | * | 50 | * |
51 | * The formula is for each component, each coefficient being multiplied by | 51 | * The first three values of each row are coded as 13-bit signed fixed-point |
52 | * 1024 and each constant being multiplied by 16: | 52 | * numbers, with 10 bits for the fractional part. The fourth value is a |
53 | * constant coded as a 14-bit signed fixed-point number with 4 bits for the | ||
54 | * fractional part. | ||
55 | * | ||
56 | * The values in table order give the following colorspace translation: | ||
53 | * G = 1.164 * Y - 0.391 * U - 0.813 * V + 135 | 57 | * G = 1.164 * Y - 0.391 * U - 0.813 * V + 135 |
54 | * R = 1.164 * Y + 1.596 * V - 222 | 58 | * R = 1.164 * Y + 1.596 * V - 222 |
55 | * B = 1.164 * Y + 2.018 * U + 276 | 59 | * B = 1.164 * Y + 2.018 * U + 276 |
@@ -155,6 +159,36 @@ static int sun4i_backend_drm_format_to_layer(u32 format, u32 *mode) | |||
155 | return 0; | 159 | return 0; |
156 | } | 160 | } |
157 | 161 | ||
162 | static const uint32_t sun4i_backend_formats[] = { | ||
163 | DRM_FORMAT_ARGB1555, | ||
164 | DRM_FORMAT_ARGB4444, | ||
165 | DRM_FORMAT_ARGB8888, | ||
166 | DRM_FORMAT_BGRX8888, | ||
167 | DRM_FORMAT_RGB565, | ||
168 | DRM_FORMAT_RGB888, | ||
169 | DRM_FORMAT_RGBA4444, | ||
170 | DRM_FORMAT_RGBA5551, | ||
171 | DRM_FORMAT_UYVY, | ||
172 | DRM_FORMAT_VYUY, | ||
173 | DRM_FORMAT_XRGB8888, | ||
174 | DRM_FORMAT_YUYV, | ||
175 | DRM_FORMAT_YVYU, | ||
176 | }; | ||
177 | |||
178 | bool sun4i_backend_format_is_supported(uint32_t fmt, uint64_t modifier) | ||
179 | { | ||
180 | unsigned int i; | ||
181 | |||
182 | if (modifier != DRM_FORMAT_MOD_LINEAR) | ||
183 | return false; | ||
184 | |||
185 | for (i = 0; i < ARRAY_SIZE(sun4i_backend_formats); i++) | ||
186 | if (sun4i_backend_formats[i] == fmt) | ||
187 | return true; | ||
188 | |||
189 | return false; | ||
190 | } | ||
191 | |||
158 | int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, | 192 | int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, |
159 | int layer, struct drm_plane *plane) | 193 | int layer, struct drm_plane *plane) |
160 | { | 194 | { |
@@ -395,6 +429,15 @@ int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer, | |||
395 | return 0; | 429 | return 0; |
396 | } | 430 | } |
397 | 431 | ||
432 | void sun4i_backend_cleanup_layer(struct sun4i_backend *backend, | ||
433 | int layer) | ||
434 | { | ||
435 | regmap_update_bits(backend->engine.regs, | ||
436 | SUN4I_BACKEND_ATTCTL_REG0(layer), | ||
437 | SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN | | ||
438 | SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN, 0); | ||
439 | } | ||
440 | |||
398 | static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state) | 441 | static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state) |
399 | { | 442 | { |
400 | u16 src_h = state->src_h >> 16; | 443 | u16 src_h = state->src_h >> 16; |
@@ -413,11 +456,50 @@ static bool sun4i_backend_plane_uses_frontend(struct drm_plane_state *state) | |||
413 | { | 456 | { |
414 | struct sun4i_layer *layer = plane_to_sun4i_layer(state->plane); | 457 | struct sun4i_layer *layer = plane_to_sun4i_layer(state->plane); |
415 | struct sun4i_backend *backend = layer->backend; | 458 | struct sun4i_backend *backend = layer->backend; |
459 | uint32_t format = state->fb->format->format; | ||
460 | uint64_t modifier = state->fb->modifier; | ||
416 | 461 | ||
417 | if (IS_ERR(backend->frontend)) | 462 | if (IS_ERR(backend->frontend)) |
418 | return false; | 463 | return false; |
419 | 464 | ||
420 | return sun4i_backend_plane_uses_scaler(state); | 465 | if (!sun4i_frontend_format_is_supported(format, modifier)) |
466 | return false; | ||
467 | |||
468 | if (!sun4i_backend_format_is_supported(format, modifier)) | ||
469 | return true; | ||
470 | |||
471 | /* | ||
472 | * TODO: The backend alone allows 2x and 4x integer scaling, including | ||
473 | * support for an alpha component (which the frontend doesn't support). | ||
474 | * Use the backend directly instead of the frontend in this case, with | ||
475 | * another test to return false. | ||
476 | */ | ||
477 | |||
478 | if (sun4i_backend_plane_uses_scaler(state)) | ||
479 | return true; | ||
480 | |||
481 | /* | ||
482 | * Here the format is supported by both the frontend and the backend | ||
483 | * and no frontend scaling is required, so use the backend directly. | ||
484 | */ | ||
485 | return false; | ||
486 | } | ||
487 | |||
488 | static bool sun4i_backend_plane_is_supported(struct drm_plane_state *state, | ||
489 | bool *uses_frontend) | ||
490 | { | ||
491 | if (sun4i_backend_plane_uses_frontend(state)) { | ||
492 | *uses_frontend = true; | ||
493 | return true; | ||
494 | } | ||
495 | |||
496 | *uses_frontend = false; | ||
497 | |||
498 | /* Scaling is not supported without the frontend. */ | ||
499 | if (sun4i_backend_plane_uses_scaler(state)) | ||
500 | return false; | ||
501 | |||
502 | return true; | ||
421 | } | 503 | } |
422 | 504 | ||
423 | static void sun4i_backend_atomic_begin(struct sunxi_engine *engine, | 505 | static void sun4i_backend_atomic_begin(struct sunxi_engine *engine, |
@@ -460,14 +542,19 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, | |||
460 | struct drm_framebuffer *fb = plane_state->fb; | 542 | struct drm_framebuffer *fb = plane_state->fb; |
461 | struct drm_format_name_buf format_name; | 543 | struct drm_format_name_buf format_name; |
462 | 544 | ||
463 | if (sun4i_backend_plane_uses_frontend(plane_state)) { | 545 | if (!sun4i_backend_plane_is_supported(plane_state, |
546 | &layer_state->uses_frontend)) | ||
547 | return -EINVAL; | ||
548 | |||
549 | if (layer_state->uses_frontend) { | ||
464 | DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", | 550 | DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", |
465 | plane->index); | 551 | plane->index); |
466 | |||
467 | layer_state->uses_frontend = true; | ||
468 | num_frontend_planes++; | 552 | num_frontend_planes++; |
469 | } else { | 553 | } else { |
470 | layer_state->uses_frontend = false; | 554 | if (fb->format->is_yuv) { |
555 | DRM_DEBUG_DRIVER("Plane FB format is YUV\n"); | ||
556 | num_yuv_planes++; | ||
557 | } | ||
471 | } | 558 | } |
472 | 559 | ||
473 | DRM_DEBUG_DRIVER("Plane FB format is %s\n", | 560 | DRM_DEBUG_DRIVER("Plane FB format is %s\n", |
@@ -476,11 +563,6 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, | |||
476 | if (fb->format->has_alpha || (plane_state->alpha != DRM_BLEND_ALPHA_OPAQUE)) | 563 | if (fb->format->has_alpha || (plane_state->alpha != DRM_BLEND_ALPHA_OPAQUE)) |
477 | num_alpha_planes++; | 564 | num_alpha_planes++; |
478 | 565 | ||
479 | if (fb->format->is_yuv) { | ||
480 | DRM_DEBUG_DRIVER("Plane FB format is YUV\n"); | ||
481 | num_yuv_planes++; | ||
482 | } | ||
483 | |||
484 | DRM_DEBUG_DRIVER("Plane zpos is %d\n", | 566 | DRM_DEBUG_DRIVER("Plane zpos is %d\n", |
485 | plane_state->normalized_zpos); | 567 | plane_state->normalized_zpos); |
486 | 568 | ||
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h index e3d4c6035eb2..01f66463271b 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.h +++ b/drivers/gpu/drm/sun4i/sun4i_backend.h | |||
@@ -198,6 +198,7 @@ engine_to_sun4i_backend(struct sunxi_engine *engine) | |||
198 | 198 | ||
199 | void sun4i_backend_layer_enable(struct sun4i_backend *backend, | 199 | void sun4i_backend_layer_enable(struct sun4i_backend *backend, |
200 | int layer, bool enable); | 200 | int layer, bool enable); |
201 | bool sun4i_backend_format_is_supported(uint32_t fmt, uint64_t modifier); | ||
201 | int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, | 202 | int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, |
202 | int layer, struct drm_plane *plane); | 203 | int layer, struct drm_plane *plane); |
203 | int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, | 204 | int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, |
@@ -208,5 +209,7 @@ int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend, | |||
208 | int layer, uint32_t in_fmt); | 209 | int layer, uint32_t in_fmt); |
209 | int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, | 210 | int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, |
210 | int layer, struct drm_plane *plane); | 211 | int layer, struct drm_plane *plane); |
212 | void sun4i_backend_cleanup_layer(struct sun4i_backend *backend, | ||
213 | int layer); | ||
211 | 214 | ||
212 | #endif /* _SUN4I_BACKEND_H_ */ | 215 | #endif /* _SUN4I_BACKEND_H_ */ |
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index ef773d36baf0..ccdeae6299eb 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c | |||
@@ -28,6 +28,16 @@ | |||
28 | #include "sun4i_tcon.h" | 28 | #include "sun4i_tcon.h" |
29 | #include "sun8i_tcon_top.h" | 29 | #include "sun8i_tcon_top.h" |
30 | 30 | ||
31 | static int drm_sun4i_gem_dumb_create(struct drm_file *file_priv, | ||
32 | struct drm_device *drm, | ||
33 | struct drm_mode_create_dumb *args) | ||
34 | { | ||
35 | /* The hardware only allows even pitches for YUV buffers. */ | ||
36 | args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8), 2); | ||
37 | |||
38 | return drm_gem_cma_dumb_create_internal(file_priv, drm, args); | ||
39 | } | ||
40 | |||
31 | DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops); | 41 | DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops); |
32 | 42 | ||
33 | static struct drm_driver sun4i_drv_driver = { | 43 | static struct drm_driver sun4i_drv_driver = { |
@@ -42,7 +52,7 @@ static struct drm_driver sun4i_drv_driver = { | |||
42 | .minor = 0, | 52 | .minor = 0, |
43 | 53 | ||
44 | /* GEM Operations */ | 54 | /* GEM Operations */ |
45 | .dumb_create = drm_gem_cma_dumb_create, | 55 | .dumb_create = drm_sun4i_gem_dumb_create, |
46 | .gem_free_object_unlocked = drm_gem_cma_free_object, | 56 | .gem_free_object_unlocked = drm_gem_cma_free_object, |
47 | .gem_vm_ops = &drm_gem_cma_vm_ops, | 57 | .gem_vm_ops = &drm_gem_cma_vm_ops, |
48 | 58 | ||
diff --git a/drivers/gpu/drm/sun4i/sun4i_frontend.c b/drivers/gpu/drm/sun4i/sun4i_frontend.c index ddf6cfa6dd23..1a7ebc45747e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_frontend.c +++ b/drivers/gpu/drm/sun4i/sun4i_frontend.c | |||
@@ -107,8 +107,34 @@ EXPORT_SYMBOL(sun4i_frontend_update_buffer); | |||
107 | static int sun4i_frontend_drm_format_to_input_fmt(uint32_t fmt, u32 *val) | 107 | static int sun4i_frontend_drm_format_to_input_fmt(uint32_t fmt, u32 *val) |
108 | { | 108 | { |
109 | switch (fmt) { | 109 | switch (fmt) { |
110 | case DRM_FORMAT_ARGB8888: | 110 | case DRM_FORMAT_XRGB8888: |
111 | *val = 5; | 111 | *val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_RGB; |
112 | return 0; | ||
113 | |||
114 | default: | ||
115 | return -EINVAL; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static int sun4i_frontend_drm_format_to_input_mode(uint32_t fmt, u32 *val) | ||
120 | { | ||
121 | if (drm_format_num_planes(fmt) == 1) | ||
122 | *val = SUN4I_FRONTEND_INPUT_FMT_DATA_MOD_PACKED; | ||
123 | else | ||
124 | return -EINVAL; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int sun4i_frontend_drm_format_to_input_sequence(uint32_t fmt, u32 *val) | ||
130 | { | ||
131 | switch (fmt) { | ||
132 | case DRM_FORMAT_BGRX8888: | ||
133 | *val = SUN4I_FRONTEND_INPUT_FMT_DATA_PS_BGRX; | ||
134 | return 0; | ||
135 | |||
136 | case DRM_FORMAT_XRGB8888: | ||
137 | *val = SUN4I_FRONTEND_INPUT_FMT_DATA_PS_XRGB; | ||
112 | return 0; | 138 | return 0; |
113 | 139 | ||
114 | default: | 140 | default: |
@@ -119,9 +145,12 @@ static int sun4i_frontend_drm_format_to_input_fmt(uint32_t fmt, u32 *val) | |||
119 | static int sun4i_frontend_drm_format_to_output_fmt(uint32_t fmt, u32 *val) | 145 | static int sun4i_frontend_drm_format_to_output_fmt(uint32_t fmt, u32 *val) |
120 | { | 146 | { |
121 | switch (fmt) { | 147 | switch (fmt) { |
148 | case DRM_FORMAT_BGRX8888: | ||
149 | *val = SUN4I_FRONTEND_OUTPUT_FMT_DATA_FMT_BGRX8888; | ||
150 | return 0; | ||
151 | |||
122 | case DRM_FORMAT_XRGB8888: | 152 | case DRM_FORMAT_XRGB8888: |
123 | case DRM_FORMAT_ARGB8888: | 153 | *val = SUN4I_FRONTEND_OUTPUT_FMT_DATA_FMT_XRGB8888; |
124 | *val = 2; | ||
125 | return 0; | 154 | return 0; |
126 | 155 | ||
127 | default: | 156 | default: |
@@ -129,22 +158,54 @@ static int sun4i_frontend_drm_format_to_output_fmt(uint32_t fmt, u32 *val) | |||
129 | } | 158 | } |
130 | } | 159 | } |
131 | 160 | ||
161 | static const uint32_t sun4i_frontend_formats[] = { | ||
162 | DRM_FORMAT_BGRX8888, | ||
163 | DRM_FORMAT_XRGB8888, | ||
164 | }; | ||
165 | |||
166 | bool sun4i_frontend_format_is_supported(uint32_t fmt, uint64_t modifier) | ||
167 | { | ||
168 | unsigned int i; | ||
169 | |||
170 | if (modifier != DRM_FORMAT_MOD_LINEAR) | ||
171 | return false; | ||
172 | |||
173 | for (i = 0; i < ARRAY_SIZE(sun4i_frontend_formats); i++) | ||
174 | if (sun4i_frontend_formats[i] == fmt) | ||
175 | return true; | ||
176 | |||
177 | return false; | ||
178 | } | ||
179 | EXPORT_SYMBOL(sun4i_frontend_format_is_supported); | ||
180 | |||
132 | int sun4i_frontend_update_formats(struct sun4i_frontend *frontend, | 181 | int sun4i_frontend_update_formats(struct sun4i_frontend *frontend, |
133 | struct drm_plane *plane, uint32_t out_fmt) | 182 | struct drm_plane *plane, uint32_t out_fmt) |
134 | { | 183 | { |
135 | struct drm_plane_state *state = plane->state; | 184 | struct drm_plane_state *state = plane->state; |
136 | struct drm_framebuffer *fb = state->fb; | 185 | struct drm_framebuffer *fb = state->fb; |
186 | uint32_t format = fb->format->format; | ||
137 | u32 out_fmt_val; | 187 | u32 out_fmt_val; |
138 | u32 in_fmt_val; | 188 | u32 in_fmt_val, in_mod_val, in_ps_val; |
139 | int ret; | 189 | int ret; |
140 | 190 | ||
141 | ret = sun4i_frontend_drm_format_to_input_fmt(fb->format->format, | 191 | ret = sun4i_frontend_drm_format_to_input_fmt(format, &in_fmt_val); |
142 | &in_fmt_val); | ||
143 | if (ret) { | 192 | if (ret) { |
144 | DRM_DEBUG_DRIVER("Invalid input format\n"); | 193 | DRM_DEBUG_DRIVER("Invalid input format\n"); |
145 | return ret; | 194 | return ret; |
146 | } | 195 | } |
147 | 196 | ||
197 | ret = sun4i_frontend_drm_format_to_input_mode(format, &in_mod_val); | ||
198 | if (ret) { | ||
199 | DRM_DEBUG_DRIVER("Invalid input mode\n"); | ||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | ret = sun4i_frontend_drm_format_to_input_sequence(format, &in_ps_val); | ||
204 | if (ret) { | ||
205 | DRM_DEBUG_DRIVER("Invalid pixel sequence\n"); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
148 | ret = sun4i_frontend_drm_format_to_output_fmt(out_fmt, &out_fmt_val); | 209 | ret = sun4i_frontend_drm_format_to_output_fmt(out_fmt, &out_fmt_val); |
149 | if (ret) { | 210 | if (ret) { |
150 | DRM_DEBUG_DRIVER("Invalid output format\n"); | 211 | DRM_DEBUG_DRIVER("Invalid output format\n"); |
@@ -162,10 +223,12 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend, | |||
162 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE1_REG, 0x400); | 223 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE1_REG, 0x400); |
163 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE1_REG, 0x400); | 224 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE1_REG, 0x400); |
164 | 225 | ||
226 | regmap_update_bits(frontend->regs, SUN4I_FRONTEND_BYPASS_REG, | ||
227 | SUN4I_FRONTEND_BYPASS_CSC_EN, | ||
228 | SUN4I_FRONTEND_BYPASS_CSC_EN); | ||
229 | |||
165 | regmap_write(frontend->regs, SUN4I_FRONTEND_INPUT_FMT_REG, | 230 | regmap_write(frontend->regs, SUN4I_FRONTEND_INPUT_FMT_REG, |
166 | SUN4I_FRONTEND_INPUT_FMT_DATA_MOD(1) | | 231 | in_mod_val | in_fmt_val | in_ps_val); |
167 | SUN4I_FRONTEND_INPUT_FMT_DATA_FMT(in_fmt_val) | | ||
168 | SUN4I_FRONTEND_INPUT_FMT_PS(1)); | ||
169 | 232 | ||
170 | /* | 233 | /* |
171 | * TODO: It look like the A31 and A80 at least will need the | 234 | * TODO: It look like the A31 and A80 at least will need the |
@@ -173,7 +236,7 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend, | |||
173 | * ARGB8888). | 236 | * ARGB8888). |
174 | */ | 237 | */ |
175 | regmap_write(frontend->regs, SUN4I_FRONTEND_OUTPUT_FMT_REG, | 238 | regmap_write(frontend->regs, SUN4I_FRONTEND_OUTPUT_FMT_REG, |
176 | SUN4I_FRONTEND_OUTPUT_FMT_DATA_FMT(out_fmt_val)); | 239 | out_fmt_val); |
177 | 240 | ||
178 | return 0; | 241 | return 0; |
179 | } | 242 | } |
@@ -183,16 +246,24 @@ void sun4i_frontend_update_coord(struct sun4i_frontend *frontend, | |||
183 | struct drm_plane *plane) | 246 | struct drm_plane *plane) |
184 | { | 247 | { |
185 | struct drm_plane_state *state = plane->state; | 248 | struct drm_plane_state *state = plane->state; |
249 | struct drm_framebuffer *fb = state->fb; | ||
250 | uint32_t luma_width, luma_height; | ||
251 | uint32_t chroma_width, chroma_height; | ||
186 | 252 | ||
187 | /* Set height and width */ | 253 | /* Set height and width */ |
188 | DRM_DEBUG_DRIVER("Frontend size W: %u H: %u\n", | 254 | DRM_DEBUG_DRIVER("Frontend size W: %u H: %u\n", |
189 | state->crtc_w, state->crtc_h); | 255 | state->crtc_w, state->crtc_h); |
256 | |||
257 | luma_width = state->src_w >> 16; | ||
258 | luma_height = state->src_h >> 16; | ||
259 | |||
260 | chroma_width = DIV_ROUND_UP(luma_width, fb->format->hsub); | ||
261 | chroma_height = DIV_ROUND_UP(luma_height, fb->format->vsub); | ||
262 | |||
190 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_INSIZE_REG, | 263 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_INSIZE_REG, |
191 | SUN4I_FRONTEND_INSIZE(state->src_h >> 16, | 264 | SUN4I_FRONTEND_INSIZE(luma_height, luma_width)); |
192 | state->src_w >> 16)); | ||
193 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_INSIZE_REG, | 265 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_INSIZE_REG, |
194 | SUN4I_FRONTEND_INSIZE(state->src_h >> 16, | 266 | SUN4I_FRONTEND_INSIZE(chroma_height, chroma_width)); |
195 | state->src_w >> 16)); | ||
196 | 267 | ||
197 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_OUTSIZE_REG, | 268 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_OUTSIZE_REG, |
198 | SUN4I_FRONTEND_OUTSIZE(state->crtc_h, state->crtc_w)); | 269 | SUN4I_FRONTEND_OUTSIZE(state->crtc_h, state->crtc_w)); |
@@ -200,14 +271,14 @@ void sun4i_frontend_update_coord(struct sun4i_frontend *frontend, | |||
200 | SUN4I_FRONTEND_OUTSIZE(state->crtc_h, state->crtc_w)); | 271 | SUN4I_FRONTEND_OUTSIZE(state->crtc_h, state->crtc_w)); |
201 | 272 | ||
202 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZFACT_REG, | 273 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZFACT_REG, |
203 | state->src_w / state->crtc_w); | 274 | (luma_width << 16) / state->crtc_w); |
204 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZFACT_REG, | 275 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZFACT_REG, |
205 | state->src_w / state->crtc_w); | 276 | (chroma_width << 16) / state->crtc_w); |
206 | 277 | ||
207 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTFACT_REG, | 278 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTFACT_REG, |
208 | state->src_h / state->crtc_h); | 279 | (luma_height << 16) / state->crtc_h); |
209 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTFACT_REG, | 280 | regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTFACT_REG, |
210 | state->src_h / state->crtc_h); | 281 | (chroma_height << 16) / state->crtc_h); |
211 | 282 | ||
212 | regmap_write_bits(frontend->regs, SUN4I_FRONTEND_FRM_CTRL_REG, | 283 | regmap_write_bits(frontend->regs, SUN4I_FRONTEND_FRM_CTRL_REG, |
213 | SUN4I_FRONTEND_FRM_CTRL_REG_RDY, | 284 | SUN4I_FRONTEND_FRM_CTRL_REG_RDY, |
@@ -339,10 +410,6 @@ static int sun4i_frontend_runtime_resume(struct device *dev) | |||
339 | SUN4I_FRONTEND_EN_EN, | 410 | SUN4I_FRONTEND_EN_EN, |
340 | SUN4I_FRONTEND_EN_EN); | 411 | SUN4I_FRONTEND_EN_EN); |
341 | 412 | ||
342 | regmap_update_bits(frontend->regs, SUN4I_FRONTEND_BYPASS_REG, | ||
343 | SUN4I_FRONTEND_BYPASS_CSC_EN, | ||
344 | SUN4I_FRONTEND_BYPASS_CSC_EN); | ||
345 | |||
346 | sun4i_frontend_scaler_init(frontend); | 413 | sun4i_frontend_scaler_init(frontend); |
347 | 414 | ||
348 | return 0; | 415 | return 0; |
diff --git a/drivers/gpu/drm/sun4i/sun4i_frontend.h b/drivers/gpu/drm/sun4i/sun4i_frontend.h index 02661ce81f3e..ad146e8d8d70 100644 --- a/drivers/gpu/drm/sun4i/sun4i_frontend.h +++ b/drivers/gpu/drm/sun4i/sun4i_frontend.h | |||
@@ -26,12 +26,14 @@ | |||
26 | #define SUN4I_FRONTEND_LINESTRD0_REG 0x040 | 26 | #define SUN4I_FRONTEND_LINESTRD0_REG 0x040 |
27 | 27 | ||
28 | #define SUN4I_FRONTEND_INPUT_FMT_REG 0x04c | 28 | #define SUN4I_FRONTEND_INPUT_FMT_REG 0x04c |
29 | #define SUN4I_FRONTEND_INPUT_FMT_DATA_MOD(mod) ((mod) << 8) | 29 | #define SUN4I_FRONTEND_INPUT_FMT_DATA_MOD_PACKED (1 << 8) |
30 | #define SUN4I_FRONTEND_INPUT_FMT_DATA_FMT(fmt) ((fmt) << 4) | 30 | #define SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_RGB (5 << 4) |
31 | #define SUN4I_FRONTEND_INPUT_FMT_PS(ps) (ps) | 31 | #define SUN4I_FRONTEND_INPUT_FMT_DATA_PS_BGRX 0 |
32 | #define SUN4I_FRONTEND_INPUT_FMT_DATA_PS_XRGB 1 | ||
32 | 33 | ||
33 | #define SUN4I_FRONTEND_OUTPUT_FMT_REG 0x05c | 34 | #define SUN4I_FRONTEND_OUTPUT_FMT_REG 0x05c |
34 | #define SUN4I_FRONTEND_OUTPUT_FMT_DATA_FMT(fmt) (fmt) | 35 | #define SUN4I_FRONTEND_OUTPUT_FMT_DATA_FMT_BGRX8888 1 |
36 | #define SUN4I_FRONTEND_OUTPUT_FMT_DATA_FMT_XRGB8888 2 | ||
35 | 37 | ||
36 | #define SUN4I_FRONTEND_CH0_INSIZE_REG 0x100 | 38 | #define SUN4I_FRONTEND_CH0_INSIZE_REG 0x100 |
37 | #define SUN4I_FRONTEND_INSIZE(h, w) ((((h) - 1) << 16) | (((w) - 1))) | 39 | #define SUN4I_FRONTEND_INSIZE(h, w) ((((h) - 1) << 16) | (((w) - 1))) |
@@ -95,5 +97,6 @@ void sun4i_frontend_update_coord(struct sun4i_frontend *frontend, | |||
95 | struct drm_plane *plane); | 97 | struct drm_plane *plane); |
96 | int sun4i_frontend_update_formats(struct sun4i_frontend *frontend, | 98 | int sun4i_frontend_update_formats(struct sun4i_frontend *frontend, |
97 | struct drm_plane *plane, uint32_t out_fmt); | 99 | struct drm_plane *plane, uint32_t out_fmt); |
100 | bool sun4i_frontend_format_is_supported(uint32_t fmt, uint64_t modifier); | ||
98 | 101 | ||
99 | #endif /* _SUN4I_FRONTEND_H_ */ | 102 | #endif /* _SUN4I_FRONTEND_H_ */ |
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 78f77af8805a..29631e0efde3 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <drm/drm_atomic_helper.h> | 13 | #include <drm/drm_atomic_helper.h> |
14 | #include <drm/drm_plane_helper.h> | 14 | #include <drm/drm_plane_helper.h> |
15 | #include <drm/drm_gem_framebuffer_helper.h> | ||
15 | #include <drm/drmP.h> | 16 | #include <drm/drmP.h> |
16 | 17 | ||
17 | #include "sun4i_backend.h" | 18 | #include "sun4i_backend.h" |
@@ -92,14 +93,16 @@ static void sun4i_backend_layer_atomic_update(struct drm_plane *plane, | |||
92 | struct sun4i_backend *backend = layer->backend; | 93 | struct sun4i_backend *backend = layer->backend; |
93 | struct sun4i_frontend *frontend = backend->frontend; | 94 | struct sun4i_frontend *frontend = backend->frontend; |
94 | 95 | ||
96 | sun4i_backend_cleanup_layer(backend, layer->id); | ||
97 | |||
95 | if (layer_state->uses_frontend) { | 98 | if (layer_state->uses_frontend) { |
96 | sun4i_frontend_init(frontend); | 99 | sun4i_frontend_init(frontend); |
97 | sun4i_frontend_update_coord(frontend, plane); | 100 | sun4i_frontend_update_coord(frontend, plane); |
98 | sun4i_frontend_update_buffer(frontend, plane); | 101 | sun4i_frontend_update_buffer(frontend, plane); |
99 | sun4i_frontend_update_formats(frontend, plane, | 102 | sun4i_frontend_update_formats(frontend, plane, |
100 | DRM_FORMAT_ARGB8888); | 103 | DRM_FORMAT_XRGB8888); |
101 | sun4i_backend_update_layer_frontend(backend, layer->id, | 104 | sun4i_backend_update_layer_frontend(backend, layer->id, |
102 | DRM_FORMAT_ARGB8888); | 105 | DRM_FORMAT_XRGB8888); |
103 | sun4i_frontend_enable(frontend); | 106 | sun4i_frontend_enable(frontend); |
104 | } else { | 107 | } else { |
105 | sun4i_backend_update_layer_formats(backend, layer->id, plane); | 108 | sun4i_backend_update_layer_formats(backend, layer->id, plane); |
@@ -112,6 +115,7 @@ static void sun4i_backend_layer_atomic_update(struct drm_plane *plane, | |||
112 | } | 115 | } |
113 | 116 | ||
114 | static const struct drm_plane_helper_funcs sun4i_backend_layer_helper_funcs = { | 117 | static const struct drm_plane_helper_funcs sun4i_backend_layer_helper_funcs = { |
118 | .prepare_fb = drm_gem_fb_prepare_fb, | ||
115 | .atomic_disable = sun4i_backend_layer_atomic_disable, | 119 | .atomic_disable = sun4i_backend_layer_atomic_disable, |
116 | .atomic_update = sun4i_backend_layer_atomic_update, | 120 | .atomic_update = sun4i_backend_layer_atomic_update, |
117 | }; | 121 | }; |
@@ -125,10 +129,11 @@ static const struct drm_plane_funcs sun4i_backend_layer_funcs = { | |||
125 | .update_plane = drm_atomic_helper_update_plane, | 129 | .update_plane = drm_atomic_helper_update_plane, |
126 | }; | 130 | }; |
127 | 131 | ||
128 | static const uint32_t sun4i_backend_layer_formats[] = { | 132 | static const uint32_t sun4i_layer_formats[] = { |
129 | DRM_FORMAT_ARGB8888, | 133 | DRM_FORMAT_ARGB8888, |
130 | DRM_FORMAT_ARGB4444, | 134 | DRM_FORMAT_ARGB4444, |
131 | DRM_FORMAT_ARGB1555, | 135 | DRM_FORMAT_ARGB1555, |
136 | DRM_FORMAT_BGRX8888, | ||
132 | DRM_FORMAT_RGBA5551, | 137 | DRM_FORMAT_RGBA5551, |
133 | DRM_FORMAT_RGBA4444, | 138 | DRM_FORMAT_RGBA4444, |
134 | DRM_FORMAT_RGB888, | 139 | DRM_FORMAT_RGB888, |
@@ -154,8 +159,8 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, | |||
154 | /* possible crtcs are set later */ | 159 | /* possible crtcs are set later */ |
155 | ret = drm_universal_plane_init(drm, &layer->plane, 0, | 160 | ret = drm_universal_plane_init(drm, &layer->plane, 0, |
156 | &sun4i_backend_layer_funcs, | 161 | &sun4i_backend_layer_funcs, |
157 | sun4i_backend_layer_formats, | 162 | sun4i_layer_formats, |
158 | ARRAY_SIZE(sun4i_backend_layer_formats), | 163 | ARRAY_SIZE(sun4i_layer_formats), |
159 | NULL, type, NULL); | 164 | NULL, type, NULL); |
160 | if (ret) { | 165 | if (ret) { |
161 | dev_err(drm->dev, "Couldn't initialize layer\n"); | 166 | dev_err(drm->dev, "Couldn't initialize layer\n"); |
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c index e3fc8fa920fb..18534263a05d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <drm/drm_crtc_helper.h> | 19 | #include <drm/drm_crtc_helper.h> |
20 | #include <drm/drm_fb_cma_helper.h> | 20 | #include <drm/drm_fb_cma_helper.h> |
21 | #include <drm/drm_gem_cma_helper.h> | 21 | #include <drm/drm_gem_cma_helper.h> |
22 | #include <drm/drm_gem_framebuffer_helper.h> | ||
22 | #include <drm/drm_plane_helper.h> | 23 | #include <drm/drm_plane_helper.h> |
23 | #include <drm/drmP.h> | 24 | #include <drm/drmP.h> |
24 | 25 | ||
@@ -300,6 +301,7 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane, | |||
300 | } | 301 | } |
301 | 302 | ||
302 | static struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = { | 303 | static struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = { |
304 | .prepare_fb = drm_gem_fb_prepare_fb, | ||
303 | .atomic_check = sun8i_ui_layer_atomic_check, | 305 | .atomic_check = sun8i_ui_layer_atomic_check, |
304 | .atomic_disable = sun8i_ui_layer_atomic_disable, | 306 | .atomic_disable = sun8i_ui_layer_atomic_disable, |
305 | .atomic_update = sun8i_ui_layer_atomic_update, | 307 | .atomic_update = sun8i_ui_layer_atomic_update, |
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c index 4249edfb47ed..87be898f9b7a 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <drm/drm_crtc_helper.h> | 13 | #include <drm/drm_crtc_helper.h> |
14 | #include <drm/drm_fb_cma_helper.h> | 14 | #include <drm/drm_fb_cma_helper.h> |
15 | #include <drm/drm_gem_cma_helper.h> | 15 | #include <drm/drm_gem_cma_helper.h> |
16 | #include <drm/drm_gem_framebuffer_helper.h> | ||
16 | #include <drm/drm_plane_helper.h> | 17 | #include <drm/drm_plane_helper.h> |
17 | #include <drm/drmP.h> | 18 | #include <drm/drmP.h> |
18 | 19 | ||
@@ -336,6 +337,7 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane, | |||
336 | } | 337 | } |
337 | 338 | ||
338 | static struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = { | 339 | static struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = { |
340 | .prepare_fb = drm_gem_fb_prepare_fb, | ||
339 | .atomic_check = sun8i_vi_layer_atomic_check, | 341 | .atomic_check = sun8i_vi_layer_atomic_check, |
340 | .atomic_disable = sun8i_vi_layer_atomic_disable, | 342 | .atomic_disable = sun8i_vi_layer_atomic_disable, |
341 | .atomic_update = sun8i_vi_layer_atomic_update, | 343 | .atomic_update = sun8i_vi_layer_atomic_update, |
diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c index 72efcecb44f7..28e2d03c0ccf 100644 --- a/drivers/gpu/drm/tve200/tve200_drv.c +++ b/drivers/gpu/drm/tve200/tve200_drv.c | |||
@@ -249,7 +249,7 @@ static int tve200_probe(struct platform_device *pdev) | |||
249 | clk_disable: | 249 | clk_disable: |
250 | clk_disable_unprepare(priv->pclk); | 250 | clk_disable_unprepare(priv->pclk); |
251 | dev_unref: | 251 | dev_unref: |
252 | drm_dev_unref(drm); | 252 | drm_dev_put(drm); |
253 | return ret; | 253 | return ret; |
254 | } | 254 | } |
255 | 255 | ||
@@ -263,7 +263,7 @@ static int tve200_remove(struct platform_device *pdev) | |||
263 | drm_panel_bridge_remove(priv->bridge); | 263 | drm_panel_bridge_remove(priv->bridge); |
264 | drm_mode_config_cleanup(drm); | 264 | drm_mode_config_cleanup(drm); |
265 | clk_disable_unprepare(priv->pclk); | 265 | clk_disable_unprepare(priv->pclk); |
266 | drm_dev_unref(drm); | 266 | drm_dev_put(drm); |
267 | 267 | ||
268 | return 0; | 268 | return 0; |
269 | } | 269 | } |
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index b88c96911453..1e8947c7d954 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c | |||
@@ -210,14 +210,11 @@ static void | |||
210 | v3d_attach_object_fences(struct v3d_exec_info *exec) | 210 | v3d_attach_object_fences(struct v3d_exec_info *exec) |
211 | { | 211 | { |
212 | struct dma_fence *out_fence = exec->render_done_fence; | 212 | struct dma_fence *out_fence = exec->render_done_fence; |
213 | struct v3d_bo *bo; | ||
214 | int i; | 213 | int i; |
215 | 214 | ||
216 | for (i = 0; i < exec->bo_count; i++) { | 215 | for (i = 0; i < exec->bo_count; i++) { |
217 | bo = to_v3d_bo(&exec->bo[i]->base); | ||
218 | |||
219 | /* XXX: Use shared fences for read-only objects. */ | 216 | /* XXX: Use shared fences for read-only objects. */ |
220 | reservation_object_add_excl_fence(bo->resv, out_fence); | 217 | reservation_object_add_excl_fence(exec->bo[i]->resv, out_fence); |
221 | } | 218 | } |
222 | } | 219 | } |
223 | 220 | ||
@@ -228,11 +225,8 @@ v3d_unlock_bo_reservations(struct drm_device *dev, | |||
228 | { | 225 | { |
229 | int i; | 226 | int i; |
230 | 227 | ||
231 | for (i = 0; i < exec->bo_count; i++) { | 228 | for (i = 0; i < exec->bo_count; i++) |
232 | struct v3d_bo *bo = to_v3d_bo(&exec->bo[i]->base); | 229 | ww_mutex_unlock(&exec->bo[i]->resv->lock); |
233 | |||
234 | ww_mutex_unlock(&bo->resv->lock); | ||
235 | } | ||
236 | 230 | ||
237 | ww_acquire_fini(acquire_ctx); | 231 | ww_acquire_fini(acquire_ctx); |
238 | } | 232 | } |
@@ -251,13 +245,13 @@ v3d_lock_bo_reservations(struct drm_device *dev, | |||
251 | { | 245 | { |
252 | int contended_lock = -1; | 246 | int contended_lock = -1; |
253 | int i, ret; | 247 | int i, ret; |
254 | struct v3d_bo *bo; | ||
255 | 248 | ||
256 | ww_acquire_init(acquire_ctx, &reservation_ww_class); | 249 | ww_acquire_init(acquire_ctx, &reservation_ww_class); |
257 | 250 | ||
258 | retry: | 251 | retry: |
259 | if (contended_lock != -1) { | 252 | if (contended_lock != -1) { |
260 | bo = to_v3d_bo(&exec->bo[contended_lock]->base); | 253 | struct v3d_bo *bo = exec->bo[contended_lock]; |
254 | |||
261 | ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, | 255 | ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, |
262 | acquire_ctx); | 256 | acquire_ctx); |
263 | if (ret) { | 257 | if (ret) { |
@@ -270,19 +264,16 @@ retry: | |||
270 | if (i == contended_lock) | 264 | if (i == contended_lock) |
271 | continue; | 265 | continue; |
272 | 266 | ||
273 | bo = to_v3d_bo(&exec->bo[i]->base); | 267 | ret = ww_mutex_lock_interruptible(&exec->bo[i]->resv->lock, |
274 | 268 | acquire_ctx); | |
275 | ret = ww_mutex_lock_interruptible(&bo->resv->lock, acquire_ctx); | ||
276 | if (ret) { | 269 | if (ret) { |
277 | int j; | 270 | int j; |
278 | 271 | ||
279 | for (j = 0; j < i; j++) { | 272 | for (j = 0; j < i; j++) |
280 | bo = to_v3d_bo(&exec->bo[j]->base); | 273 | ww_mutex_unlock(&exec->bo[j]->resv->lock); |
281 | ww_mutex_unlock(&bo->resv->lock); | ||
282 | } | ||
283 | 274 | ||
284 | if (contended_lock != -1 && contended_lock >= i) { | 275 | if (contended_lock != -1 && contended_lock >= i) { |
285 | bo = to_v3d_bo(&exec->bo[contended_lock]->base); | 276 | struct v3d_bo *bo = exec->bo[contended_lock]; |
286 | 277 | ||
287 | ww_mutex_unlock(&bo->resv->lock); | 278 | ww_mutex_unlock(&bo->resv->lock); |
288 | } | 279 | } |
@@ -303,9 +294,7 @@ retry: | |||
303 | * before we commit the CL to the hardware. | 294 | * before we commit the CL to the hardware. |
304 | */ | 295 | */ |
305 | for (i = 0; i < exec->bo_count; i++) { | 296 | for (i = 0; i < exec->bo_count; i++) { |
306 | bo = to_v3d_bo(&exec->bo[i]->base); | 297 | ret = reservation_object_reserve_shared(exec->bo[i]->resv, 1); |
307 | |||
308 | ret = reservation_object_reserve_shared(bo->resv, 1); | ||
309 | if (ret) { | 298 | if (ret) { |
310 | v3d_unlock_bo_reservations(dev, exec, acquire_ctx); | 299 | v3d_unlock_bo_reservations(dev, exec, acquire_ctx); |
311 | return ret; | 300 | return ret; |
diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index 445b2ef03303..c66d0ce21435 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c | |||
@@ -41,7 +41,7 @@ v3d_job_free(struct drm_sched_job *sched_job) | |||
41 | } | 41 | } |
42 | 42 | ||
43 | /** | 43 | /** |
44 | * Returns the fences that the bin job depends on, one by one. | 44 | * Returns the fences that the bin or render job depends on, one by one. |
45 | * v3d_job_run() won't be called until all of them have been signaled. | 45 | * v3d_job_run() won't be called until all of them have been signaled. |
46 | */ | 46 | */ |
47 | static struct dma_fence * | 47 | static struct dma_fence * |
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 8f8fed471e34..b5580b11a063 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c | |||
@@ -169,6 +169,12 @@ static int virtio_gpu_conn_get_modes(struct drm_connector *connector) | |||
169 | struct drm_display_mode *mode = NULL; | 169 | struct drm_display_mode *mode = NULL; |
170 | int count, width, height; | 170 | int count, width, height; |
171 | 171 | ||
172 | if (output->edid) { | ||
173 | count = drm_add_edid_modes(connector, output->edid); | ||
174 | if (count) | ||
175 | return count; | ||
176 | } | ||
177 | |||
172 | width = le32_to_cpu(output->info.r.width); | 178 | width = le32_to_cpu(output->info.r.width); |
173 | height = le32_to_cpu(output->info.r.height); | 179 | height = le32_to_cpu(output->info.r.height); |
174 | count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); | 180 | count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); |
@@ -287,6 +293,8 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index) | |||
287 | drm_connector_init(dev, connector, &virtio_gpu_connector_funcs, | 293 | drm_connector_init(dev, connector, &virtio_gpu_connector_funcs, |
288 | DRM_MODE_CONNECTOR_VIRTUAL); | 294 | DRM_MODE_CONNECTOR_VIRTUAL); |
289 | drm_connector_helper_add(connector, &virtio_gpu_conn_helper_funcs); | 295 | drm_connector_helper_add(connector, &virtio_gpu_conn_helper_funcs); |
296 | if (vgdev->has_edid) | ||
297 | drm_connector_attach_edid_property(connector); | ||
290 | 298 | ||
291 | drm_encoder_init(dev, encoder, &virtio_gpu_enc_funcs, | 299 | drm_encoder_init(dev, encoder, &virtio_gpu_enc_funcs, |
292 | DRM_MODE_ENCODER_VIRTUAL, NULL); | 300 | DRM_MODE_ENCODER_VIRTUAL, NULL); |
@@ -378,6 +386,10 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) | |||
378 | 386 | ||
379 | void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) | 387 | void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) |
380 | { | 388 | { |
389 | int i; | ||
390 | |||
391 | for (i = 0 ; i < vgdev->num_scanouts; ++i) | ||
392 | kfree(vgdev->outputs[i].edid); | ||
381 | virtio_gpu_fbdev_fini(vgdev); | 393 | virtio_gpu_fbdev_fini(vgdev); |
382 | drm_mode_config_cleanup(vgdev->ddev); | 394 | drm_mode_config_cleanup(vgdev->ddev); |
383 | } | 395 | } |
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index d9287c144fe5..f7f32a885af7 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c | |||
@@ -80,6 +80,7 @@ static unsigned int features[] = { | |||
80 | */ | 80 | */ |
81 | VIRTIO_GPU_F_VIRGL, | 81 | VIRTIO_GPU_F_VIRGL, |
82 | #endif | 82 | #endif |
83 | VIRTIO_GPU_F_EDID, | ||
83 | }; | 84 | }; |
84 | static struct virtio_driver virtio_gpu_driver = { | 85 | static struct virtio_driver virtio_gpu_driver = { |
85 | .feature_table = features, | 86 | .feature_table = features, |
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 9db568054d66..f7e877857c1f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h | |||
@@ -115,6 +115,7 @@ struct virtio_gpu_output { | |||
115 | struct drm_encoder enc; | 115 | struct drm_encoder enc; |
116 | struct virtio_gpu_display_one info; | 116 | struct virtio_gpu_display_one info; |
117 | struct virtio_gpu_update_cursor cursor; | 117 | struct virtio_gpu_update_cursor cursor; |
118 | struct edid *edid; | ||
118 | int cur_x; | 119 | int cur_x; |
119 | int cur_y; | 120 | int cur_y; |
120 | bool enabled; | 121 | bool enabled; |
@@ -201,6 +202,7 @@ struct virtio_gpu_device { | |||
201 | struct ida ctx_id_ida; | 202 | struct ida ctx_id_ida; |
202 | 203 | ||
203 | bool has_virgl_3d; | 204 | bool has_virgl_3d; |
205 | bool has_edid; | ||
204 | 206 | ||
205 | struct work_struct config_changed_work; | 207 | struct work_struct config_changed_work; |
206 | 208 | ||
@@ -291,6 +293,7 @@ int virtio_gpu_cmd_get_capset_info(struct virtio_gpu_device *vgdev, int idx); | |||
291 | int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, | 293 | int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, |
292 | int idx, int version, | 294 | int idx, int version, |
293 | struct virtio_gpu_drv_cap_cache **cache_p); | 295 | struct virtio_gpu_drv_cap_cache **cache_p); |
296 | int virtio_gpu_cmd_get_edids(struct virtio_gpu_device *vgdev); | ||
294 | void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, | 297 | void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, |
295 | uint32_t nlen, const char *name); | 298 | uint32_t nlen, const char *name); |
296 | void virtio_gpu_cmd_context_destroy(struct virtio_gpu_device *vgdev, | 299 | void virtio_gpu_cmd_context_destroy(struct virtio_gpu_device *vgdev, |
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 691b842d5f3a..3af6181c05a8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c | |||
@@ -44,6 +44,8 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) | |||
44 | virtio_cread(vgdev->vdev, struct virtio_gpu_config, | 44 | virtio_cread(vgdev->vdev, struct virtio_gpu_config, |
45 | events_read, &events_read); | 45 | events_read, &events_read); |
46 | if (events_read & VIRTIO_GPU_EVENT_DISPLAY) { | 46 | if (events_read & VIRTIO_GPU_EVENT_DISPLAY) { |
47 | if (vgdev->has_edid) | ||
48 | virtio_gpu_cmd_get_edids(vgdev); | ||
47 | virtio_gpu_cmd_get_display_info(vgdev); | 49 | virtio_gpu_cmd_get_display_info(vgdev); |
48 | drm_helper_hpd_irq_event(vgdev->ddev); | 50 | drm_helper_hpd_irq_event(vgdev->ddev); |
49 | events_clear |= VIRTIO_GPU_EVENT_DISPLAY; | 51 | events_clear |= VIRTIO_GPU_EVENT_DISPLAY; |
@@ -156,6 +158,10 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) | |||
156 | #else | 158 | #else |
157 | DRM_INFO("virgl 3d acceleration not supported by guest\n"); | 159 | DRM_INFO("virgl 3d acceleration not supported by guest\n"); |
158 | #endif | 160 | #endif |
161 | if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_EDID)) { | ||
162 | vgdev->has_edid = true; | ||
163 | DRM_INFO("EDID support available.\n"); | ||
164 | } | ||
159 | 165 | ||
160 | ret = virtio_find_vqs(vgdev->vdev, 2, vqs, callbacks, names, NULL); | 166 | ret = virtio_find_vqs(vgdev->vdev, 2, vqs, callbacks, names, NULL); |
161 | if (ret) { | 167 | if (ret) { |
@@ -201,6 +207,8 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) | |||
201 | 207 | ||
202 | if (num_capsets) | 208 | if (num_capsets) |
203 | virtio_gpu_get_capsets(vgdev, num_capsets); | 209 | virtio_gpu_get_capsets(vgdev, num_capsets); |
210 | if (vgdev->has_edid) | ||
211 | virtio_gpu_cmd_get_edids(vgdev); | ||
204 | virtio_gpu_cmd_get_display_info(vgdev); | 212 | virtio_gpu_cmd_get_display_info(vgdev); |
205 | wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending, | 213 | wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending, |
206 | 5 * HZ); | 214 | 5 * HZ); |
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 93f2c3a51ee8..2c6764f08f18 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c | |||
@@ -584,6 +584,45 @@ static void virtio_gpu_cmd_capset_cb(struct virtio_gpu_device *vgdev, | |||
584 | wake_up(&vgdev->resp_wq); | 584 | wake_up(&vgdev->resp_wq); |
585 | } | 585 | } |
586 | 586 | ||
587 | static int virtio_get_edid_block(void *data, u8 *buf, | ||
588 | unsigned int block, size_t len) | ||
589 | { | ||
590 | struct virtio_gpu_resp_edid *resp = data; | ||
591 | size_t start = block * EDID_LENGTH; | ||
592 | |||
593 | if (start + len > le32_to_cpu(resp->size)) | ||
594 | return -1; | ||
595 | memcpy(buf, resp->edid + start, len); | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static void virtio_gpu_cmd_get_edid_cb(struct virtio_gpu_device *vgdev, | ||
600 | struct virtio_gpu_vbuffer *vbuf) | ||
601 | { | ||
602 | struct virtio_gpu_cmd_get_edid *cmd = | ||
603 | (struct virtio_gpu_cmd_get_edid *)vbuf->buf; | ||
604 | struct virtio_gpu_resp_edid *resp = | ||
605 | (struct virtio_gpu_resp_edid *)vbuf->resp_buf; | ||
606 | uint32_t scanout = le32_to_cpu(cmd->scanout); | ||
607 | struct virtio_gpu_output *output; | ||
608 | struct edid *new_edid, *old_edid; | ||
609 | |||
610 | if (scanout >= vgdev->num_scanouts) | ||
611 | return; | ||
612 | output = vgdev->outputs + scanout; | ||
613 | |||
614 | new_edid = drm_do_get_edid(&output->conn, virtio_get_edid_block, resp); | ||
615 | |||
616 | spin_lock(&vgdev->display_info_lock); | ||
617 | old_edid = output->edid; | ||
618 | output->edid = new_edid; | ||
619 | drm_connector_update_edid_property(&output->conn, output->edid); | ||
620 | spin_unlock(&vgdev->display_info_lock); | ||
621 | |||
622 | kfree(old_edid); | ||
623 | wake_up(&vgdev->resp_wq); | ||
624 | } | ||
625 | |||
587 | int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev) | 626 | int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev) |
588 | { | 627 | { |
589 | struct virtio_gpu_ctrl_hdr *cmd_p; | 628 | struct virtio_gpu_ctrl_hdr *cmd_p; |
@@ -686,6 +725,34 @@ int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, | |||
686 | return 0; | 725 | return 0; |
687 | } | 726 | } |
688 | 727 | ||
728 | int virtio_gpu_cmd_get_edids(struct virtio_gpu_device *vgdev) | ||
729 | { | ||
730 | struct virtio_gpu_cmd_get_edid *cmd_p; | ||
731 | struct virtio_gpu_vbuffer *vbuf; | ||
732 | void *resp_buf; | ||
733 | int scanout; | ||
734 | |||
735 | if (WARN_ON(!vgdev->has_edid)) | ||
736 | return -EINVAL; | ||
737 | |||
738 | for (scanout = 0; scanout < vgdev->num_scanouts; scanout++) { | ||
739 | resp_buf = kzalloc(sizeof(struct virtio_gpu_resp_edid), | ||
740 | GFP_KERNEL); | ||
741 | if (!resp_buf) | ||
742 | return -ENOMEM; | ||
743 | |||
744 | cmd_p = virtio_gpu_alloc_cmd_resp | ||
745 | (vgdev, &virtio_gpu_cmd_get_edid_cb, &vbuf, | ||
746 | sizeof(*cmd_p), sizeof(struct virtio_gpu_resp_edid), | ||
747 | resp_buf); | ||
748 | cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_GET_EDID); | ||
749 | cmd_p->scanout = cpu_to_le32(scanout); | ||
750 | virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); | ||
751 | } | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
689 | void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, | 756 | void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, |
690 | uint32_t nlen, const char *name) | 757 | uint32_t nlen, const char *name) |
691 | { | 758 | { |
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index a3d57e0f5ee5..83087877565c 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c | |||
@@ -68,7 +68,6 @@ static struct drm_driver vkms_driver = { | |||
68 | .release = vkms_release, | 68 | .release = vkms_release, |
69 | .fops = &vkms_driver_fops, | 69 | .fops = &vkms_driver_fops, |
70 | .dumb_create = vkms_dumb_create, | 70 | .dumb_create = vkms_dumb_create, |
71 | .dumb_map_offset = vkms_dumb_map, | ||
72 | .gem_vm_ops = &vkms_gem_vm_ops, | 71 | .gem_vm_ops = &vkms_gem_vm_ops, |
73 | .gem_free_object_unlocked = vkms_gem_free_object, | 72 | .gem_free_object_unlocked = vkms_gem_free_object, |
74 | .get_vblank_timestamp = vkms_get_vblank_timestamp, | 73 | .get_vblank_timestamp = vkms_get_vblank_timestamp, |
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 1c93990693e3..e4469cd3d254 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h | |||
@@ -127,9 +127,6 @@ vm_fault_t vkms_gem_fault(struct vm_fault *vmf); | |||
127 | int vkms_dumb_create(struct drm_file *file, struct drm_device *dev, | 127 | int vkms_dumb_create(struct drm_file *file, struct drm_device *dev, |
128 | struct drm_mode_create_dumb *args); | 128 | struct drm_mode_create_dumb *args); |
129 | 129 | ||
130 | int vkms_dumb_map(struct drm_file *file, struct drm_device *dev, | ||
131 | u32 handle, u64 *offset); | ||
132 | |||
133 | void vkms_gem_free_object(struct drm_gem_object *obj); | 130 | void vkms_gem_free_object(struct drm_gem_object *obj); |
134 | 131 | ||
135 | int vkms_gem_vmap(struct drm_gem_object *obj); | 132 | int vkms_gem_vmap(struct drm_gem_object *obj); |
diff --git a/drivers/gpu/drm/vkms/vkms_gem.c b/drivers/gpu/drm/vkms/vkms_gem.c index d04e988b4cbe..80311daed47a 100644 --- a/drivers/gpu/drm/vkms/vkms_gem.c +++ b/drivers/gpu/drm/vkms/vkms_gem.c | |||
@@ -153,32 +153,6 @@ int vkms_dumb_create(struct drm_file *file, struct drm_device *dev, | |||
153 | return 0; | 153 | return 0; |
154 | } | 154 | } |
155 | 155 | ||
156 | int vkms_dumb_map(struct drm_file *file, struct drm_device *dev, | ||
157 | u32 handle, u64 *offset) | ||
158 | { | ||
159 | struct drm_gem_object *obj; | ||
160 | int ret; | ||
161 | |||
162 | obj = drm_gem_object_lookup(file, handle); | ||
163 | if (!obj) | ||
164 | return -ENOENT; | ||
165 | |||
166 | if (!obj->filp) { | ||
167 | ret = -EINVAL; | ||
168 | goto unref; | ||
169 | } | ||
170 | |||
171 | ret = drm_gem_create_mmap_offset(obj); | ||
172 | if (ret) | ||
173 | goto unref; | ||
174 | |||
175 | *offset = drm_vma_node_offset_addr(&obj->vma_node); | ||
176 | unref: | ||
177 | drm_gem_object_put_unlocked(obj); | ||
178 | |||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | static struct page **_get_pages(struct vkms_gem_object *vkms_obj) | 156 | static struct page **_get_pages(struct vkms_gem_object *vkms_obj) |
183 | { | 157 | { |
184 | struct drm_gem_object *gem_obj = &vkms_obj->gem; | 158 | struct drm_gem_object *gem_obj = &vkms_obj->gem; |
diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c index 257030460fb6..d3e23dd70c1b 100644 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ b/drivers/staging/vboxvideo/vbox_drv.c | |||
@@ -279,7 +279,6 @@ static struct drm_driver driver = { | |||
279 | .gem_free_object_unlocked = vbox_gem_free_object, | 279 | .gem_free_object_unlocked = vbox_gem_free_object, |
280 | .dumb_create = vbox_dumb_create, | 280 | .dumb_create = vbox_dumb_create, |
281 | .dumb_map_offset = vbox_dumb_mmap_offset, | 281 | .dumb_map_offset = vbox_dumb_mmap_offset, |
282 | .dumb_destroy = drm_gem_dumb_destroy, | ||
283 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, | 282 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, |
284 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, | 283 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, |
285 | .gem_prime_export = drm_gem_prime_export, | 284 | .gem_prime_export = drm_gem_prime_export, |