aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-10-25 02:35:20 -0400
committerDave Airlie <airlied@redhat.com>2016-10-25 02:35:20 -0400
commit61d0a04d6f5b2122f88aacbc4b1716e571961660 (patch)
tree1f7f775b4b8f1b04144bb35b569db73eaf890eee
parent07d9a380680d1c0eb51ef87ff2eab5c994949e69 (diff)
parent8a5bbf327aa16025c78491266a6425807c7fbee0 (diff)
Merge tag 'topic/drm-misc-2016-10-24' of git://anongit.freedesktop.org/drm-intel into drm-next
First -misc pull for 4.10: - drm_format rework from Laurent - reservation patches from Chris that missed 4.9. - aspect ratio support in infoframe helpers and drm mode/edid code (Shashank Sharma) - rotation rework from Ville (first parts at least) - another attempt at the CRC debugfs interface from Tomeu - piles and piles of misc patches all over * tag 'topic/drm-misc-2016-10-24' of git://anongit.freedesktop.org/drm-intel: (55 commits) drm: Use u64 for intermediate dotclock calculations drm/i915: Use the per-plane rotation property drm/omap: Use per-plane rotation property drm/omap: Set rotation property initial value to BIT(DRM_ROTATE_0) insted of 0 drm/atmel-hlcdc: Use per-plane rotation property drm/arm: Use per-plane rotation property drm: Add support for optional per-plane rotation property drm/atomic: Reject attempts to use multiple rotation angles at once drm: Add drm_rotation_90_or_270() dma-buf/sync_file: hold reference to fence when creating sync_file drm/virtio: kconfig: Fixup white space. drm/fence: release fence reference when canceling event drm/i915: Handle early failure during intel_get_load_detect_pipe drm/fb_cma_helper: do not free fbdev if there is none drm: fix sparse warnings on undeclared symbols in crc debugfs gpu: Remove depends on RESET_CONTROLLER when not a provider i915: don't call drm_atomic_state_put on invalid pointer drm: Don't export the drm_fb_get_bpp_depth() function drm/arm: mali-dp: Replace drm_fb_get_bpp_depth() with drm_format_plane_cpp() drm: vmwgfx: Replace drm_fb_get_bpp_depth() with drm_format_info() ...
-rw-r--r--Documentation/gpu/drm-kms.rst3
-rw-r--r--Documentation/gpu/drm-uapi.rst6
-rw-r--r--drivers/dma-buf/reservation.c112
-rw-r--r--drivers/dma-buf/sync_file.c2
-rw-r--r--drivers/gpu/drm/Makefile3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c9
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c5
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c7
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c13
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c3
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c41
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c6
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_main.c4
-rw-r--r--drivers/gpu/drm/drm_atomic.c33
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c109
-rw-r--r--drivers/gpu/drm/drm_blend.c35
-rw-r--r--drivers/gpu/drm/drm_crtc.c37
-rw-r--r--drivers/gpu/drm/drm_debugfs.c34
-rw-r--r--drivers/gpu/drm/drm_debugfs_crc.c352
-rw-r--r--drivers/gpu/drm/drm_edid.c46
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c26
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c28
-rw-r--r--drivers/gpu/drm/drm_fops.c4
-rw-r--r--drivers/gpu/drm/drm_fourcc.c281
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c102
-rw-r--r--drivers/gpu/drm/drm_internal.h16
-rw-r--r--drivers/gpu/drm/drm_irq.c4
-rw-r--r--drivers/gpu/drm/drm_modes.c51
-rw-r--r--drivers/gpu/drm/drm_modeset_helper.c17
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem.c24
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c3
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c23
-rw-r--r--drivers/gpu/drm/gma500/gtt.c2
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c5
-rw-r--r--drivers/gpu/drm/i915/intel_atomic_plane.c3
-rw-r--r--drivers/gpu/drm/i915/intel_display.c109
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h9
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c2
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c12
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c18
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.c3
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c21
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c13
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c53
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c3
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c3
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig1
-rw-r--r--drivers/gpu/drm/savage/savage_state.c1
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c3
-rw-r--r--drivers/gpu/drm/tegra/Kconfig1
-rw-r--r--drivers/gpu/drm/tegra/drm.c3
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c18
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c2
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_plane.c7
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c3
-rw-r--r--drivers/gpu/drm/virtio/Kconfig6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c12
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c2
-rw-r--r--drivers/gpu/ipu-v3/Kconfig1
-rw-r--r--drivers/gpu/vga/vgaarb.c15
-rw-r--r--drivers/video/hdmi.c4
-rw-r--r--include/drm/drm_atomic.h42
-rw-r--r--include/drm/drm_blend.h8
-rw-r--r--include/drm/drm_crtc.h48
-rw-r--r--include/drm/drm_debugfs_crc.h73
-rw-r--r--include/drm/drm_encoder.h2
-rw-r--r--include/drm/drm_fourcc.h23
-rw-r--r--include/drm/drm_plane.h3
-rw-r--r--include/linux/fence.h56
-rw-r--r--include/linux/hdmi.h2
-rw-r--r--include/uapi/drm/drm_mode.h24
75 files changed, 1355 insertions, 759 deletions
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 53b872c105d2..cb0d3537b705 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -63,6 +63,9 @@ Frame Buffer Functions Reference
63DRM Format Handling 63DRM Format Handling
64=================== 64===================
65 65
66.. kernel-doc:: include/drm/drm_fourcc.h
67 :internal:
68
66.. kernel-doc:: drivers/gpu/drm/drm_fourcc.c 69.. kernel-doc:: drivers/gpu/drm/drm_fourcc.c
67 :export: 70 :export:
68 71
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
index 1ba301cebe16..de3ac9f90f8f 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -216,3 +216,9 @@ interfaces. Especially since all hardware-acceleration interfaces to
216userspace are driver specific for efficiency and other reasons these 216userspace are driver specific for efficiency and other reasons these
217interfaces can be rather substantial. Hence every driver has its own 217interfaces can be rather substantial. Hence every driver has its own
218chapter. 218chapter.
219
220Testing and validation
221======================
222
223.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
224 :doc: CRC ABI
diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 723d8af988e5..82de59f7cbbd 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -280,18 +280,24 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
280 unsigned *pshared_count, 280 unsigned *pshared_count,
281 struct fence ***pshared) 281 struct fence ***pshared)
282{ 282{
283 unsigned shared_count = 0; 283 struct fence **shared = NULL;
284 unsigned retry = 1; 284 struct fence *fence_excl;
285 struct fence **shared = NULL, *fence_excl = NULL; 285 unsigned int shared_count;
286 int ret = 0; 286 int ret = 1;
287 287
288 while (retry) { 288 do {
289 struct reservation_object_list *fobj; 289 struct reservation_object_list *fobj;
290 unsigned seq; 290 unsigned seq;
291 unsigned int i;
291 292
292 seq = read_seqcount_begin(&obj->seq); 293 shared_count = i = 0;
293 294
294 rcu_read_lock(); 295 rcu_read_lock();
296 seq = read_seqcount_begin(&obj->seq);
297
298 fence_excl = rcu_dereference(obj->fence_excl);
299 if (fence_excl && !fence_get_rcu(fence_excl))
300 goto unlock;
295 301
296 fobj = rcu_dereference(obj->fence); 302 fobj = rcu_dereference(obj->fence);
297 if (fobj) { 303 if (fobj) {
@@ -309,52 +315,37 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
309 } 315 }
310 316
311 ret = -ENOMEM; 317 ret = -ENOMEM;
312 shared_count = 0;
313 break; 318 break;
314 } 319 }
315 shared = nshared; 320 shared = nshared;
316 memcpy(shared, fobj->shared, sz);
317 shared_count = fobj->shared_count; 321 shared_count = fobj->shared_count;
318 } else
319 shared_count = 0;
320 fence_excl = rcu_dereference(obj->fence_excl);
321
322 retry = read_seqcount_retry(&obj->seq, seq);
323 if (retry)
324 goto unlock;
325
326 if (!fence_excl || fence_get_rcu(fence_excl)) {
327 unsigned i;
328 322
329 for (i = 0; i < shared_count; ++i) { 323 for (i = 0; i < shared_count; ++i) {
330 if (fence_get_rcu(shared[i])) 324 shared[i] = rcu_dereference(fobj->shared[i]);
331 continue; 325 if (!fence_get_rcu(shared[i]))
332 326 break;
333 /* uh oh, refcount failed, abort and retry */
334 while (i--)
335 fence_put(shared[i]);
336
337 if (fence_excl) {
338 fence_put(fence_excl);
339 fence_excl = NULL;
340 }
341
342 retry = 1;
343 break;
344 } 327 }
345 } else 328 }
346 retry = 1;
347 329
330 if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) {
331 while (i--)
332 fence_put(shared[i]);
333 fence_put(fence_excl);
334 goto unlock;
335 }
336
337 ret = 0;
348unlock: 338unlock:
349 rcu_read_unlock(); 339 rcu_read_unlock();
350 } 340 } while (ret);
351 *pshared_count = shared_count; 341
352 if (shared_count) 342 if (!shared_count) {
353 *pshared = shared;
354 else {
355 *pshared = NULL;
356 kfree(shared); 343 kfree(shared);
344 shared = NULL;
357 } 345 }
346
347 *pshared_count = shared_count;
348 *pshared = shared;
358 *pfence_excl = fence_excl; 349 *pfence_excl = fence_excl;
359 350
360 return ret; 351 return ret;
@@ -397,9 +388,6 @@ retry:
397 if (fobj) 388 if (fobj)
398 shared_count = fobj->shared_count; 389 shared_count = fobj->shared_count;
399 390
400 if (read_seqcount_retry(&obj->seq, seq))
401 goto unlock_retry;
402
403 for (i = 0; i < shared_count; ++i) { 391 for (i = 0; i < shared_count; ++i) {
404 struct fence *lfence = rcu_dereference(fobj->shared[i]); 392 struct fence *lfence = rcu_dereference(fobj->shared[i]);
405 393
@@ -422,9 +410,6 @@ retry:
422 if (!shared_count) { 410 if (!shared_count) {
423 struct fence *fence_excl = rcu_dereference(obj->fence_excl); 411 struct fence *fence_excl = rcu_dereference(obj->fence_excl);
424 412
425 if (read_seqcount_retry(&obj->seq, seq))
426 goto unlock_retry;
427
428 if (fence_excl && 413 if (fence_excl &&
429 !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence_excl->flags)) { 414 !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence_excl->flags)) {
430 if (!fence_get_rcu(fence_excl)) 415 if (!fence_get_rcu(fence_excl))
@@ -439,6 +424,11 @@ retry:
439 424
440 rcu_read_unlock(); 425 rcu_read_unlock();
441 if (fence) { 426 if (fence) {
427 if (read_seqcount_retry(&obj->seq, seq)) {
428 fence_put(fence);
429 goto retry;
430 }
431
442 ret = fence_wait_timeout(fence, intr, ret); 432 ret = fence_wait_timeout(fence, intr, ret);
443 fence_put(fence); 433 fence_put(fence);
444 if (ret > 0 && wait_all && (i + 1 < shared_count)) 434 if (ret > 0 && wait_all && (i + 1 < shared_count))
@@ -484,12 +474,13 @@ bool reservation_object_test_signaled_rcu(struct reservation_object *obj,
484 bool test_all) 474 bool test_all)
485{ 475{
486 unsigned seq, shared_count; 476 unsigned seq, shared_count;
487 int ret = true; 477 int ret;
488 478
479 rcu_read_lock();
489retry: 480retry:
481 ret = true;
490 shared_count = 0; 482 shared_count = 0;
491 seq = read_seqcount_begin(&obj->seq); 483 seq = read_seqcount_begin(&obj->seq);
492 rcu_read_lock();
493 484
494 if (test_all) { 485 if (test_all) {
495 unsigned i; 486 unsigned i;
@@ -500,46 +491,35 @@ retry:
500 if (fobj) 491 if (fobj)
501 shared_count = fobj->shared_count; 492 shared_count = fobj->shared_count;
502 493
503 if (read_seqcount_retry(&obj->seq, seq))
504 goto unlock_retry;
505
506 for (i = 0; i < shared_count; ++i) { 494 for (i = 0; i < shared_count; ++i) {
507 struct fence *fence = rcu_dereference(fobj->shared[i]); 495 struct fence *fence = rcu_dereference(fobj->shared[i]);
508 496
509 ret = reservation_object_test_signaled_single(fence); 497 ret = reservation_object_test_signaled_single(fence);
510 if (ret < 0) 498 if (ret < 0)
511 goto unlock_retry; 499 goto retry;
512 else if (!ret) 500 else if (!ret)
513 break; 501 break;
514 } 502 }
515 503
516 /* 504 if (read_seqcount_retry(&obj->seq, seq))
517 * There could be a read_seqcount_retry here, but nothing cares 505 goto retry;
518 * about whether it's the old or newer fence pointers that are
519 * signaled. That race could still have happened after checking
520 * read_seqcount_retry. If you care, use ww_mutex_lock.
521 */
522 } 506 }
523 507
524 if (!shared_count) { 508 if (!shared_count) {
525 struct fence *fence_excl = rcu_dereference(obj->fence_excl); 509 struct fence *fence_excl = rcu_dereference(obj->fence_excl);
526 510
527 if (read_seqcount_retry(&obj->seq, seq))
528 goto unlock_retry;
529
530 if (fence_excl) { 511 if (fence_excl) {
531 ret = reservation_object_test_signaled_single( 512 ret = reservation_object_test_signaled_single(
532 fence_excl); 513 fence_excl);
533 if (ret < 0) 514 if (ret < 0)
534 goto unlock_retry; 515 goto retry;
516
517 if (read_seqcount_retry(&obj->seq, seq))
518 goto retry;
535 } 519 }
536 } 520 }
537 521
538 rcu_read_unlock(); 522 rcu_read_unlock();
539 return ret; 523 return ret;
540
541unlock_retry:
542 rcu_read_unlock();
543 goto retry;
544} 524}
545EXPORT_SYMBOL_GPL(reservation_object_test_signaled_rcu); 525EXPORT_SYMBOL_GPL(reservation_object_test_signaled_rcu);
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index b29a9e817320..235f8ac113cc 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -79,7 +79,7 @@ struct sync_file *sync_file_create(struct fence *fence)
79 if (!sync_file) 79 if (!sync_file)
80 return NULL; 80 return NULL;
81 81
82 sync_file->fence = fence; 82 sync_file->fence = fence_get(fence);
83 83
84 snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d", 84 snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d",
85 fence->ops->get_driver_name(fence), 85 fence->ops->get_driver_name(fence),
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 25c720454017..74579d2e796e 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -9,7 +9,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
9 drm_scatter.o drm_pci.o \ 9 drm_scatter.o drm_pci.o \
10 drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ 10 drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
11 drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \ 11 drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \
12 drm_info.o drm_debugfs.o drm_encoder_slave.o \ 12 drm_info.o drm_encoder_slave.o \
13 drm_trace_points.o drm_global.o drm_prime.o \ 13 drm_trace_points.o drm_global.o drm_prime.o \
14 drm_rect.o drm_vma_manager.o drm_flip_work.o \ 14 drm_rect.o drm_vma_manager.o drm_flip_work.o \
15 drm_modeset_lock.o drm_atomic.o drm_bridge.o \ 15 drm_modeset_lock.o drm_atomic.o drm_bridge.o \
@@ -23,6 +23,7 @@ drm-$(CONFIG_PCI) += ati_pcigart.o
23drm-$(CONFIG_DRM_PANEL) += drm_panel.o 23drm-$(CONFIG_DRM_PANEL) += drm_panel.o
24drm-$(CONFIG_OF) += drm_of.o 24drm-$(CONFIG_OF) += drm_of.o
25drm-$(CONFIG_AGP) += drm_agpsupport.o 25drm-$(CONFIG_AGP) += drm_agpsupport.o
26drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
26 27
27drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ 28drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
28 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ 29 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 9fb8aa4d6bae..8d01aa24d68a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -90,12 +90,12 @@ static struct fb_ops amdgpufb_ops = {
90}; 90};
91 91
92 92
93int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tiled) 93int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int cpp, bool tiled)
94{ 94{
95 int aligned = width; 95 int aligned = width;
96 int pitch_mask = 0; 96 int pitch_mask = 0;
97 97
98 switch (bpp / 8) { 98 switch (cpp) {
99 case 1: 99 case 1:
100 pitch_mask = 255; 100 pitch_mask = 255;
101 break; 101 break;
@@ -110,7 +110,7 @@ int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tile
110 110
111 aligned += pitch_mask; 111 aligned += pitch_mask;
112 aligned &= ~pitch_mask; 112 aligned &= ~pitch_mask;
113 return aligned; 113 return aligned * cpp;
114} 114}
115 115
116static void amdgpufb_destroy_pinned_object(struct drm_gem_object *gobj) 116static void amdgpufb_destroy_pinned_object(struct drm_gem_object *gobj)
@@ -139,13 +139,13 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
139 int ret; 139 int ret;
140 int aligned_size, size; 140 int aligned_size, size;
141 int height = mode_cmd->height; 141 int height = mode_cmd->height;
142 u32 bpp, depth; 142 u32 cpp;
143 143
144 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); 144 cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
145 145
146 /* need to align pitch with crtc limits */ 146 /* need to align pitch with crtc limits */
147 mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, bpp, 147 mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp,
148 fb_tiled) * ((bpp + 1) / 8); 148 fb_tiled);
149 149
150 height = ALIGN(mode_cmd->height, 8); 150 height = ALIGN(mode_cmd->height, 8);
151 size = mode_cmd->pitches[0] * height; 151 size = mode_cmd->pitches[0] * height;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index a7ea9a3b454e..3ad0bf6ce3e4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -407,10 +407,8 @@ int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
407 return -ENOENT; 407 return -ENOENT;
408 } 408 }
409 robj = gem_to_amdgpu_bo(gobj); 409 robj = gem_to_amdgpu_bo(gobj);
410 if (timeout == 0) 410 ret = reservation_object_wait_timeout_rcu(robj->tbo.resv, true, true,
411 ret = reservation_object_test_signaled_rcu(robj->tbo.resv, true); 411 timeout);
412 else
413 ret = reservation_object_wait_timeout_rcu(robj->tbo.resv, true, true, timeout);
414 412
415 /* ret == 0 means not signaled, 413 /* ret == 0 means not signaled,
416 * ret > 0 means signaled 414 * ret > 0 means signaled
@@ -704,7 +702,8 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
704 uint32_t handle; 702 uint32_t handle;
705 int r; 703 int r;
706 704
707 args->pitch = amdgpu_align_pitch(adev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8); 705 args->pitch = amdgpu_align_pitch(adev, args->width,
706 DIV_ROUND_UP(args->bpp, 8), 0);
708 args->size = (u64)args->pitch * args->height; 707 args->size = (u64)args->pitch * args->height;
709 args->size = ALIGN(args->size, PAGE_SIZE); 708 args->size = ALIGN(args->size, PAGE_SIZE);
710 709
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 48019ae22ddb..bbaa55add2d2 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -223,14 +223,12 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
223{ 223{
224 struct hdlcd_drm_private *hdlcd; 224 struct hdlcd_drm_private *hdlcd;
225 struct drm_gem_cma_object *gem; 225 struct drm_gem_cma_object *gem;
226 unsigned int depth, bpp;
227 u32 src_w, src_h, dest_w, dest_h; 226 u32 src_w, src_h, dest_w, dest_h;
228 dma_addr_t scanout_start; 227 dma_addr_t scanout_start;
229 228
230 if (!plane->state->fb) 229 if (!plane->state->fb)
231 return; 230 return;
232 231
233 drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp);
234 src_w = plane->state->src_w >> 16; 232 src_w = plane->state->src_w >> 16;
235 src_h = plane->state->src_h >> 16; 233 src_h = plane->state->src_h >> 16;
236 dest_w = plane->state->crtc_w; 234 dest_w = plane->state->crtc_w;
@@ -238,7 +236,8 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
238 gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); 236 gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0);
239 scanout_start = gem->paddr + plane->state->fb->offsets[0] + 237 scanout_start = gem->paddr + plane->state->fb->offsets[0] +
240 plane->state->crtc_y * plane->state->fb->pitches[0] + 238 plane->state->crtc_y * plane->state->fb->pitches[0] +
241 plane->state->crtc_x * bpp / 8; 239 plane->state->crtc_x *
240 drm_format_plane_cpp(plane->state->fb->pixel_format, 0);
242 241
243 hdlcd = plane->dev->dev_private; 242 hdlcd = plane->dev->dev_private;
244 hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, plane->state->fb->pitches[0]); 243 hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, plane->state->fb->pitches[0]);
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index a6132f1d58c1..be815d0cc772 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -198,9 +198,6 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode *
198 198
199static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt) 199static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt)
200{ 200{
201 unsigned int depth;
202 int bpp;
203
204 /* RGB888 or BGR888 can't be rotated */ 201 /* RGB888 or BGR888 can't be rotated */
205 if ((fmt == DRM_FORMAT_RGB888) || (fmt == DRM_FORMAT_BGR888)) 202 if ((fmt == DRM_FORMAT_RGB888) || (fmt == DRM_FORMAT_BGR888))
206 return -EINVAL; 203 return -EINVAL;
@@ -210,9 +207,7 @@ static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
210 * worth of pixel data. Required size is then: 207 * worth of pixel data. Required size is then:
211 * size = rotated_width * (bpp / 8) * 8; 208 * size = rotated_width * (bpp / 8) * 8;
212 */ 209 */
213 drm_fb_get_bpp_depth(fmt, &depth, &bpp); 210 return w * drm_format_plane_cpp(fmt, 0) * 8;
214
215 return w * bpp;
216} 211}
217 212
218static int malidp550_query_hw(struct malidp_hw_device *hwdev) 213static int malidp550_query_hw(struct malidp_hw_device *hwdev)
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 82c193e5e0d6..abaca03b9d36 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -254,21 +254,18 @@ int malidp_de_planes_init(struct drm_device *drm)
254 if (ret < 0) 254 if (ret < 0)
255 goto cleanup; 255 goto cleanup;
256 256
257 if (!drm->mode_config.rotation_property) { 257 /* SMART layer can't be rotated */
258 if (id != DE_SMART) {
258 unsigned long flags = DRM_ROTATE_0 | 259 unsigned long flags = DRM_ROTATE_0 |
259 DRM_ROTATE_90 | 260 DRM_ROTATE_90 |
260 DRM_ROTATE_180 | 261 DRM_ROTATE_180 |
261 DRM_ROTATE_270 | 262 DRM_ROTATE_270 |
262 DRM_REFLECT_X | 263 DRM_REFLECT_X |
263 DRM_REFLECT_Y; 264 DRM_REFLECT_Y;
264 drm->mode_config.rotation_property = 265 drm_plane_create_rotation_property(&plane->base,
265 drm_mode_create_rotation_property(drm, flags); 266 DRM_ROTATE_0,
267 flags);
266 } 268 }
267 /* SMART layer can't be rotated */
268 if (drm->mode_config.rotation_property && (id != DE_SMART))
269 drm_object_attach_property(&plane->base.base,
270 drm->mode_config.rotation_property,
271 DRM_ROTATE_0);
272 269
273 drm_plane_helper_add(&plane->base, 270 drm_plane_helper_add(&plane->base,
274 &malidp_de_plane_helper_funcs); 271 &malidp_de_plane_helper_funcs);
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 5f484310bee9..9f6222895212 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -464,7 +464,7 @@ atmel_hlcdc_dc_atomic_complete(struct atmel_hlcdc_dc_commit *commit)
464 464
465 drm_atomic_helper_cleanup_planes(dev, old_state); 465 drm_atomic_helper_cleanup_planes(dev, old_state);
466 466
467 drm_atomic_state_free(old_state); 467 drm_atomic_state_put(old_state);
468 468
469 /* Complete the commit, wake up any waiter. */ 469 /* Complete the commit, wake up any waiter. */
470 spin_lock(&dc->commit.wait.lock); 470 spin_lock(&dc->commit.wait.lock);
@@ -521,6 +521,7 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
521 /* Swap the state, this is the point of no return. */ 521 /* Swap the state, this is the point of no return. */
522 drm_atomic_helper_swap_state(state, true); 522 drm_atomic_helper_swap_state(state, true);
523 523
524 drm_atomic_state_get(state);
524 if (async) 525 if (async)
525 queue_work(dc->wq, &commit->work); 526 queue_work(dc->wq, &commit->work);
526 else 527 else
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 9d4c030672f0..246ed1e33d8a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -393,7 +393,7 @@ static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
393 393
394 if ((state->base.fb->pixel_format == DRM_FORMAT_YUV422 || 394 if ((state->base.fb->pixel_format == DRM_FORMAT_YUV422 ||
395 state->base.fb->pixel_format == DRM_FORMAT_NV61) && 395 state->base.fb->pixel_format == DRM_FORMAT_NV61) &&
396 (state->base.rotation & (DRM_ROTATE_90 | DRM_ROTATE_270))) 396 drm_rotation_90_or_270(state->base.rotation))
397 cfg |= ATMEL_HLCDC_YUV422ROT; 397 cfg |= ATMEL_HLCDC_YUV422ROT;
398 398
399 atmel_hlcdc_layer_update_cfg(&plane->layer, 399 atmel_hlcdc_layer_update_cfg(&plane->layer,
@@ -628,7 +628,7 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
628 /* 628 /*
629 * Swap width and size in case of 90 or 270 degrees rotation 629 * Swap width and size in case of 90 or 270 degrees rotation
630 */ 630 */
631 if (state->base.rotation & (DRM_ROTATE_90 | DRM_ROTATE_270)) { 631 if (drm_rotation_90_or_270(state->base.rotation)) {
632 tmp = state->crtc_w; 632 tmp = state->crtc_w;
633 state->crtc_w = state->crtc_h; 633 state->crtc_w = state->crtc_h;
634 state->crtc_h = tmp; 634 state->crtc_h = tmp;
@@ -883,9 +883,9 @@ static int atmel_hlcdc_plane_atomic_get_property(struct drm_plane *p,
883 return 0; 883 return 0;
884} 884}
885 885
886static void atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane, 886static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
887 const struct atmel_hlcdc_layer_desc *desc, 887 const struct atmel_hlcdc_layer_desc *desc,
888 struct atmel_hlcdc_plane_properties *props) 888 struct atmel_hlcdc_plane_properties *props)
889{ 889{
890 struct regmap *regmap = plane->layer.hlcdc->regmap; 890 struct regmap *regmap = plane->layer.hlcdc->regmap;
891 891
@@ -902,10 +902,18 @@ static void atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
902 ATMEL_HLCDC_LAYER_GA_MASK); 902 ATMEL_HLCDC_LAYER_GA_MASK);
903 } 903 }
904 904
905 if (desc->layout.xstride && desc->layout.pstride) 905 if (desc->layout.xstride && desc->layout.pstride) {
906 drm_object_attach_property(&plane->base.base, 906 int ret;
907 plane->base.dev->mode_config.rotation_property, 907
908 DRM_ROTATE_0); 908 ret = drm_plane_create_rotation_property(&plane->base,
909 DRM_ROTATE_0,
910 DRM_ROTATE_0 |
911 DRM_ROTATE_90 |
912 DRM_ROTATE_180 |
913 DRM_ROTATE_270);
914 if (ret)
915 return ret;
916 }
909 917
910 if (desc->layout.csc) { 918 if (desc->layout.csc) {
911 /* 919 /*
@@ -925,6 +933,8 @@ static void atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
925 ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 2), 933 ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 2),
926 0x40040890); 934 0x40040890);
927 } 935 }
936
937 return 0;
928} 938}
929 939
930static struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = { 940static struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
@@ -1036,7 +1046,9 @@ atmel_hlcdc_plane_create(struct drm_device *dev,
1036 &atmel_hlcdc_layer_plane_helper_funcs); 1046 &atmel_hlcdc_layer_plane_helper_funcs);
1037 1047
1038 /* Set default property values*/ 1048 /* Set default property values*/
1039 atmel_hlcdc_plane_init_properties(plane, desc, props); 1049 ret = atmel_hlcdc_plane_init_properties(plane, desc, props);
1050 if (ret)
1051 return ERR_PTR(ret);
1040 1052
1041 return plane; 1053 return plane;
1042} 1054}
@@ -1054,15 +1066,6 @@ atmel_hlcdc_plane_create_properties(struct drm_device *dev)
1054 if (!props->alpha) 1066 if (!props->alpha)
1055 return ERR_PTR(-ENOMEM); 1067 return ERR_PTR(-ENOMEM);
1056 1068
1057 dev->mode_config.rotation_property =
1058 drm_mode_create_rotation_property(dev,
1059 DRM_ROTATE_0 |
1060 DRM_ROTATE_90 |
1061 DRM_ROTATE_180 |
1062 DRM_ROTATE_270);
1063 if (!dev->mode_config.rotation_property)
1064 return ERR_PTR(-ENOMEM);
1065
1066 return props; 1069 return props;
1067} 1070}
1068 1071
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index daecf1ad76a4..3a6309d7d8e4 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -138,12 +138,12 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
138{ 138{
139 struct drm_device *dev = afbdev->helper.dev; 139 struct drm_device *dev = afbdev->helper.dev;
140 struct cirrus_device *cdev = dev->dev_private; 140 struct cirrus_device *cdev = dev->dev_private;
141 u32 bpp, depth; 141 u32 bpp;
142 u32 size; 142 u32 size;
143 struct drm_gem_object *gobj; 143 struct drm_gem_object *gobj;
144
145 int ret = 0; 144 int ret = 0;
146 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); 145
146 bpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0) * 8;
147 147
148 if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height, 148 if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
149 bpp, mode_cmd->pitches[0])) 149 bpp, mode_cmd->pitches[0]))
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index 76bcb43e7c06..2c3c0d4072ce 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -52,10 +52,10 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
52 struct cirrus_device *cdev = dev->dev_private; 52 struct cirrus_device *cdev = dev->dev_private;
53 struct drm_gem_object *obj; 53 struct drm_gem_object *obj;
54 struct cirrus_framebuffer *cirrus_fb; 54 struct cirrus_framebuffer *cirrus_fb;
55 u32 bpp;
55 int ret; 56 int ret;
56 u32 bpp, depth;
57 57
58 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); 58 bpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0) * 8;
59 59
60 if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height, 60 if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
61 bpp, mode_cmd->pitches[0])) 61 bpp, mode_cmd->pitches[0]))
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 23739609427d..f81706387889 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -74,6 +74,8 @@ EXPORT_SYMBOL(drm_atomic_state_default_release);
74int 74int
75drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state) 75drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
76{ 76{
77 kref_init(&state->ref);
78
77 /* TODO legacy paths should maybe do a better job about 79 /* TODO legacy paths should maybe do a better job about
78 * setting this appropriately? 80 * setting this appropriately?
79 */ 81 */
@@ -215,22 +217,16 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
215EXPORT_SYMBOL(drm_atomic_state_clear); 217EXPORT_SYMBOL(drm_atomic_state_clear);
216 218
217/** 219/**
218 * drm_atomic_state_free - free all memory for an atomic state 220 * __drm_atomic_state_free - free all memory for an atomic state
219 * @state: atomic state to deallocate 221 * @ref: This atomic state to deallocate
220 * 222 *
221 * This frees all memory associated with an atomic state, including all the 223 * This frees all memory associated with an atomic state, including all the
222 * per-object state for planes, crtcs and connectors. 224 * per-object state for planes, crtcs and connectors.
223 */ 225 */
224void drm_atomic_state_free(struct drm_atomic_state *state) 226void __drm_atomic_state_free(struct kref *ref)
225{ 227{
226 struct drm_device *dev; 228 struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
227 struct drm_mode_config *config; 229 struct drm_mode_config *config = &state->dev->mode_config;
228
229 if (!state)
230 return;
231
232 dev = state->dev;
233 config = &dev->mode_config;
234 230
235 drm_atomic_state_clear(state); 231 drm_atomic_state_clear(state);
236 232
@@ -243,7 +239,7 @@ void drm_atomic_state_free(struct drm_atomic_state *state)
243 kfree(state); 239 kfree(state);
244 } 240 }
245} 241}
246EXPORT_SYMBOL(drm_atomic_state_free); 242EXPORT_SYMBOL(__drm_atomic_state_free);
247 243
248/** 244/**
249 * drm_atomic_get_crtc_state - get crtc state 245 * drm_atomic_get_crtc_state - get crtc state
@@ -709,7 +705,10 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
709 state->src_w = val; 705 state->src_w = val;
710 } else if (property == config->prop_src_h) { 706 } else if (property == config->prop_src_h) {
711 state->src_h = val; 707 state->src_h = val;
712 } else if (property == config->rotation_property) { 708 } else if (property == config->rotation_property ||
709 property == plane->rotation_property) {
710 if (!is_power_of_2(val & DRM_ROTATE_MASK))
711 return -EINVAL;
713 state->rotation = val; 712 state->rotation = val;
714 } else if (property == plane->zpos_property) { 713 } else if (property == plane->zpos_property) {
715 state->zpos = val; 714 state->zpos = val;
@@ -767,7 +766,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
767 *val = state->src_w; 766 *val = state->src_w;
768 } else if (property == config->prop_src_h) { 767 } else if (property == config->prop_src_h) {
769 *val = state->src_h; 768 *val = state->src_h;
770 } else if (property == config->rotation_property) { 769 } else if (property == config->rotation_property ||
770 property == plane->rotation_property) {
771 *val = state->rotation; 771 *val = state->rotation;
772 } else if (property == plane->zpos_property) { 772 } else if (property == plane->zpos_property) {
773 *val = state->zpos; 773 *val = state->zpos;
@@ -1742,7 +1742,7 @@ retry:
1742 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { 1742 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
1743 /* 1743 /*
1744 * Unlike commit, check_only does not clean up state. 1744 * Unlike commit, check_only does not clean up state.
1745 * Below we call drm_atomic_state_free for it. 1745 * Below we call drm_atomic_state_put for it.
1746 */ 1746 */
1747 ret = drm_atomic_check_only(state); 1747 ret = drm_atomic_check_only(state);
1748 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { 1748 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
@@ -1775,8 +1775,7 @@ out:
1775 goto retry; 1775 goto retry;
1776 } 1776 }
1777 1777
1778 if (ret || arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) 1778 drm_atomic_state_put(state);
1779 drm_atomic_state_free(state);
1780 1779
1781 drm_modeset_drop_locks(&ctx); 1780 drm_modeset_drop_locks(&ctx);
1782 drm_modeset_acquire_fini(&ctx); 1781 drm_modeset_acquire_fini(&ctx);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index c3f83476f996..f9362760bfb2 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -458,10 +458,11 @@ mode_fixup(struct drm_atomic_state *state)
458 * removed from the crtc. 458 * removed from the crtc.
459 * crtc_state->active_changed is set when crtc_state->active changes, 459 * crtc_state->active_changed is set when crtc_state->active changes,
460 * which is used for dpms. 460 * which is used for dpms.
461 * See also: drm_atomic_crtc_needs_modeset()
461 * 462 *
462 * IMPORTANT: 463 * IMPORTANT:
463 * 464 *
464 * Drivers which update ->mode_changed (e.g. in their ->atomic_check hooks if a 465 * Drivers which set ->mode_changed (e.g. in their ->atomic_check hooks if a
465 * plane update can't be done without a full modeset) _must_ call this function 466 * plane update can't be done without a full modeset) _must_ call this function
466 * afterwards after that change. It is permitted to call this function multiple 467 * afterwards after that change. It is permitted to call this function multiple
467 * times for the same update, e.g. when the ->atomic_check functions depend upon 468 * times for the same update, e.g. when the ->atomic_check functions depend upon
@@ -510,9 +511,9 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
510 511
511 for_each_connector_in_state(state, connector, connector_state, i) { 512 for_each_connector_in_state(state, connector, connector_state, i) {
512 /* 513 /*
513 * This only sets crtc->mode_changed for routing changes, 514 * This only sets crtc->connectors_changed for routing changes,
514 * drivers must set crtc->mode_changed themselves when connector 515 * drivers must set crtc->connectors_changed themselves when
515 * properties need to be updated. 516 * connector properties need to be updated.
516 */ 517 */
517 ret = update_connector_routing(state, connector, 518 ret = update_connector_routing(state, connector,
518 connector_state); 519 connector_state);
@@ -1207,7 +1208,7 @@ static void commit_tail(struct drm_atomic_state *state)
1207 1208
1208 drm_atomic_helper_commit_cleanup_done(state); 1209 drm_atomic_helper_commit_cleanup_done(state);
1209 1210
1210 drm_atomic_state_free(state); 1211 drm_atomic_state_put(state);
1211} 1212}
1212 1213
1213static void commit_work(struct work_struct *work) 1214static void commit_work(struct work_struct *work)
@@ -1289,6 +1290,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
1289 * make sure work items don't artifically stall on each another. 1290 * make sure work items don't artifically stall on each another.
1290 */ 1291 */
1291 1292
1293 drm_atomic_state_get(state);
1292 if (nonblock) 1294 if (nonblock)
1293 queue_work(system_unbound_wq, &state->commit_work); 1295 queue_work(system_unbound_wq, &state->commit_work);
1294 else 1296 else
@@ -1590,7 +1592,7 @@ EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
1590 * 1592 *
1591 * This signals completion of the atomic update @state, including any cleanup 1593 * This signals completion of the atomic update @state, including any cleanup
1592 * work. If used, it must be called right before calling 1594 * work. If used, it must be called right before calling
1593 * drm_atomic_state_free(). 1595 * drm_atomic_state_put().
1594 * 1596 *
1595 * This is part of the atomic helper support for nonblocking commits, see 1597 * This is part of the atomic helper support for nonblocking commits, see
1596 * drm_atomic_helper_setup_commit() for an overview. 1598 * drm_atomic_helper_setup_commit() for an overview.
@@ -2113,18 +2115,13 @@ retry:
2113 state->legacy_cursor_update = true; 2115 state->legacy_cursor_update = true;
2114 2116
2115 ret = drm_atomic_commit(state); 2117 ret = drm_atomic_commit(state);
2116 if (ret != 0)
2117 goto fail;
2118
2119 /* Driver takes ownership of state on successful commit. */
2120 return 0;
2121fail: 2118fail:
2122 if (ret == -EDEADLK) 2119 if (ret == -EDEADLK)
2123 goto backoff; 2120 goto backoff;
2124 2121
2125 drm_atomic_state_free(state); 2122 drm_atomic_state_put(state);
2126
2127 return ret; 2123 return ret;
2124
2128backoff: 2125backoff:
2129 drm_atomic_state_clear(state); 2126 drm_atomic_state_clear(state);
2130 drm_atomic_legacy_backoff(state); 2127 drm_atomic_legacy_backoff(state);
@@ -2186,18 +2183,13 @@ retry:
2186 goto fail; 2183 goto fail;
2187 2184
2188 ret = drm_atomic_commit(state); 2185 ret = drm_atomic_commit(state);
2189 if (ret != 0)
2190 goto fail;
2191
2192 /* Driver takes ownership of state on successful commit. */
2193 return 0;
2194fail: 2186fail:
2195 if (ret == -EDEADLK) 2187 if (ret == -EDEADLK)
2196 goto backoff; 2188 goto backoff;
2197 2189
2198 drm_atomic_state_free(state); 2190 drm_atomic_state_put(state);
2199
2200 return ret; 2191 return ret;
2192
2201backoff: 2193backoff:
2202 drm_atomic_state_clear(state); 2194 drm_atomic_state_clear(state);
2203 drm_atomic_legacy_backoff(state); 2195 drm_atomic_legacy_backoff(state);
@@ -2326,18 +2318,13 @@ retry:
2326 goto fail; 2318 goto fail;
2327 2319
2328 ret = drm_atomic_commit(state); 2320 ret = drm_atomic_commit(state);
2329 if (ret != 0)
2330 goto fail;
2331
2332 /* Driver takes ownership of state on successful commit. */
2333 return 0;
2334fail: 2321fail:
2335 if (ret == -EDEADLK) 2322 if (ret == -EDEADLK)
2336 goto backoff; 2323 goto backoff;
2337 2324
2338 drm_atomic_state_free(state); 2325 drm_atomic_state_put(state);
2339
2340 return ret; 2326 return ret;
2327
2341backoff: 2328backoff:
2342 drm_atomic_state_clear(state); 2329 drm_atomic_state_clear(state);
2343 drm_atomic_legacy_backoff(state); 2330 drm_atomic_legacy_backoff(state);
@@ -2412,7 +2399,7 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set,
2412 primary_state->crtc_h = vdisplay; 2399 primary_state->crtc_h = vdisplay;
2413 primary_state->src_x = set->x << 16; 2400 primary_state->src_x = set->x << 16;
2414 primary_state->src_y = set->y << 16; 2401 primary_state->src_y = set->y << 16;
2415 if (primary_state->rotation & (DRM_ROTATE_90 | DRM_ROTATE_270)) { 2402 if (drm_rotation_90_or_270(primary_state->rotation)) {
2416 primary_state->src_w = vdisplay << 16; 2403 primary_state->src_w = vdisplay << 16;
2417 primary_state->src_h = hdisplay << 16; 2404 primary_state->src_h = hdisplay << 16;
2418 } else { 2405 } else {
@@ -2479,11 +2466,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
2479 } 2466 }
2480 2467
2481 err = drm_atomic_commit(state); 2468 err = drm_atomic_commit(state);
2482
2483free: 2469free:
2484 if (err < 0) 2470 drm_atomic_state_put(state);
2485 drm_atomic_state_free(state);
2486
2487 return err; 2471 return err;
2488} 2472}
2489EXPORT_SYMBOL(drm_atomic_helper_disable_all); 2473EXPORT_SYMBOL(drm_atomic_helper_disable_all);
@@ -2534,7 +2518,7 @@ retry:
2534 2518
2535 err = drm_atomic_helper_disable_all(dev, &ctx); 2519 err = drm_atomic_helper_disable_all(dev, &ctx);
2536 if (err < 0) { 2520 if (err < 0) {
2537 drm_atomic_state_free(state); 2521 drm_atomic_state_put(state);
2538 state = ERR_PTR(err); 2522 state = ERR_PTR(err);
2539 goto unlock; 2523 goto unlock;
2540 } 2524 }
@@ -2623,18 +2607,13 @@ retry:
2623 goto fail; 2607 goto fail;
2624 2608
2625 ret = drm_atomic_commit(state); 2609 ret = drm_atomic_commit(state);
2626 if (ret != 0)
2627 goto fail;
2628
2629 /* Driver takes ownership of state on successful commit. */
2630 return 0;
2631fail: 2610fail:
2632 if (ret == -EDEADLK) 2611 if (ret == -EDEADLK)
2633 goto backoff; 2612 goto backoff;
2634 2613
2635 drm_atomic_state_free(state); 2614 drm_atomic_state_put(state);
2636
2637 return ret; 2615 return ret;
2616
2638backoff: 2617backoff:
2639 drm_atomic_state_clear(state); 2618 drm_atomic_state_clear(state);
2640 drm_atomic_legacy_backoff(state); 2619 drm_atomic_legacy_backoff(state);
@@ -2683,18 +2662,13 @@ retry:
2683 goto fail; 2662 goto fail;
2684 2663
2685 ret = drm_atomic_commit(state); 2664 ret = drm_atomic_commit(state);
2686 if (ret != 0)
2687 goto fail;
2688
2689 /* Driver takes ownership of state on successful commit. */
2690 return 0;
2691fail: 2665fail:
2692 if (ret == -EDEADLK) 2666 if (ret == -EDEADLK)
2693 goto backoff; 2667 goto backoff;
2694 2668
2695 drm_atomic_state_free(state); 2669 drm_atomic_state_put(state);
2696
2697 return ret; 2670 return ret;
2671
2698backoff: 2672backoff:
2699 drm_atomic_state_clear(state); 2673 drm_atomic_state_clear(state);
2700 drm_atomic_legacy_backoff(state); 2674 drm_atomic_legacy_backoff(state);
@@ -2743,18 +2717,13 @@ retry:
2743 goto fail; 2717 goto fail;
2744 2718
2745 ret = drm_atomic_commit(state); 2719 ret = drm_atomic_commit(state);
2746 if (ret != 0)
2747 goto fail;
2748
2749 /* Driver takes ownership of state on successful commit. */
2750 return 0;
2751fail: 2720fail:
2752 if (ret == -EDEADLK) 2721 if (ret == -EDEADLK)
2753 goto backoff; 2722 goto backoff;
2754 2723
2755 drm_atomic_state_free(state); 2724 drm_atomic_state_put(state);
2756
2757 return ret; 2725 return ret;
2726
2758backoff: 2727backoff:
2759 drm_atomic_state_clear(state); 2728 drm_atomic_state_clear(state);
2760 drm_atomic_legacy_backoff(state); 2729 drm_atomic_legacy_backoff(state);
@@ -2827,18 +2796,13 @@ retry:
2827 } 2796 }
2828 2797
2829 ret = drm_atomic_nonblocking_commit(state); 2798 ret = drm_atomic_nonblocking_commit(state);
2830 if (ret != 0)
2831 goto fail;
2832
2833 /* Driver takes ownership of state on successful commit. */
2834 return 0;
2835fail: 2799fail:
2836 if (ret == -EDEADLK) 2800 if (ret == -EDEADLK)
2837 goto backoff; 2801 goto backoff;
2838 2802
2839 drm_atomic_state_free(state); 2803 drm_atomic_state_put(state);
2840
2841 return ret; 2804 return ret;
2805
2842backoff: 2806backoff:
2843 drm_atomic_state_clear(state); 2807 drm_atomic_state_clear(state);
2844 drm_atomic_legacy_backoff(state); 2808 drm_atomic_legacy_backoff(state);
@@ -2914,19 +2878,14 @@ retry:
2914 crtc_state->active = active; 2878 crtc_state->active = active;
2915 2879
2916 ret = drm_atomic_commit(state); 2880 ret = drm_atomic_commit(state);
2917 if (ret != 0)
2918 goto fail;
2919
2920 /* Driver takes ownership of state on successful commit. */
2921 return 0;
2922fail: 2881fail:
2923 if (ret == -EDEADLK) 2882 if (ret == -EDEADLK)
2924 goto backoff; 2883 goto backoff;
2925 2884
2926 connector->dpms = old_mode; 2885 connector->dpms = old_mode;
2927 drm_atomic_state_free(state); 2886 drm_atomic_state_put(state);
2928
2929 return ret; 2887 return ret;
2888
2930backoff: 2889backoff:
2931 drm_atomic_state_clear(state); 2890 drm_atomic_state_clear(state);
2932 drm_atomic_legacy_backoff(state); 2891 drm_atomic_legacy_backoff(state);
@@ -3333,7 +3292,7 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
3333 3292
3334free: 3293free:
3335 if (err < 0) { 3294 if (err < 0) {
3336 drm_atomic_state_free(state); 3295 drm_atomic_state_put(state);
3337 state = ERR_PTR(err); 3296 state = ERR_PTR(err);
3338 } 3297 }
3339 3298
@@ -3448,22 +3407,14 @@ retry:
3448 goto fail; 3407 goto fail;
3449 3408
3450 ret = drm_atomic_commit(state); 3409 ret = drm_atomic_commit(state);
3451 if (ret)
3452 goto fail;
3453
3454 /* Driver takes ownership of state on successful commit. */
3455
3456 drm_property_unreference_blob(blob);
3457
3458 return 0;
3459fail: 3410fail:
3460 if (ret == -EDEADLK) 3411 if (ret == -EDEADLK)
3461 goto backoff; 3412 goto backoff;
3462 3413
3463 drm_atomic_state_free(state); 3414 drm_atomic_state_put(state);
3464 drm_property_unreference_blob(blob); 3415 drm_property_unreference_blob(blob);
3465
3466 return ret; 3416 return ret;
3417
3467backoff: 3418backoff:
3468 drm_atomic_state_clear(state); 3419 drm_atomic_state_clear(state);
3469 drm_atomic_legacy_backoff(state); 3420 drm_atomic_legacy_backoff(state);
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 85172a977bf3..e52aece30900 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -162,6 +162,41 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
162} 162}
163EXPORT_SYMBOL(drm_mode_create_rotation_property); 163EXPORT_SYMBOL(drm_mode_create_rotation_property);
164 164
165int drm_plane_create_rotation_property(struct drm_plane *plane,
166 unsigned int rotation,
167 unsigned int supported_rotations)
168{
169 static const struct drm_prop_enum_list props[] = {
170 { __builtin_ffs(DRM_ROTATE_0) - 1, "rotate-0" },
171 { __builtin_ffs(DRM_ROTATE_90) - 1, "rotate-90" },
172 { __builtin_ffs(DRM_ROTATE_180) - 1, "rotate-180" },
173 { __builtin_ffs(DRM_ROTATE_270) - 1, "rotate-270" },
174 { __builtin_ffs(DRM_REFLECT_X) - 1, "reflect-x" },
175 { __builtin_ffs(DRM_REFLECT_Y) - 1, "reflect-y" },
176 };
177 struct drm_property *prop;
178
179 WARN_ON((supported_rotations & DRM_ROTATE_MASK) == 0);
180 WARN_ON(!is_power_of_2(rotation & DRM_ROTATE_MASK));
181 WARN_ON(rotation & ~supported_rotations);
182
183 prop = drm_property_create_bitmask(plane->dev, 0, "rotation",
184 props, ARRAY_SIZE(props),
185 supported_rotations);
186 if (!prop)
187 return -ENOMEM;
188
189 drm_object_attach_property(&plane->base, prop, rotation);
190
191 if (plane->state)
192 plane->state->rotation = rotation;
193
194 plane->rotation_property = prop;
195
196 return 0;
197}
198EXPORT_SYMBOL(drm_plane_create_rotation_property);
199
165/** 200/**
166 * drm_rotation_simplify() - Try to simplify the rotation 201 * drm_rotation_simplify() - Try to simplify the rotation
167 * @rotation: Rotation to be simplified 202 * @rotation: Rotation to be simplified
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 2d7bedf28647..13441e21117c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -40,7 +40,7 @@
40#include <drm/drm_modeset_lock.h> 40#include <drm/drm_modeset_lock.h>
41#include <drm/drm_atomic.h> 41#include <drm/drm_atomic.h>
42#include <drm/drm_auth.h> 42#include <drm/drm_auth.h>
43#include <drm/drm_framebuffer.h> 43#include <drm/drm_debugfs_crc.h>
44 44
45#include "drm_crtc_internal.h" 45#include "drm_crtc_internal.h"
46#include "drm_internal.h" 46#include "drm_internal.h"
@@ -122,6 +122,10 @@ static int drm_crtc_register_all(struct drm_device *dev)
122 int ret = 0; 122 int ret = 0;
123 123
124 drm_for_each_crtc(crtc, dev) { 124 drm_for_each_crtc(crtc, dev) {
125 if (drm_debugfs_crtc_add(crtc))
126 DRM_ERROR("Failed to initialize debugfs entry for CRTC '%s'.\n",
127 crtc->name);
128
125 if (crtc->funcs->late_register) 129 if (crtc->funcs->late_register)
126 ret = crtc->funcs->late_register(crtc); 130 ret = crtc->funcs->late_register(crtc);
127 if (ret) 131 if (ret)
@@ -138,9 +142,29 @@ static void drm_crtc_unregister_all(struct drm_device *dev)
138 drm_for_each_crtc(crtc, dev) { 142 drm_for_each_crtc(crtc, dev) {
139 if (crtc->funcs->early_unregister) 143 if (crtc->funcs->early_unregister)
140 crtc->funcs->early_unregister(crtc); 144 crtc->funcs->early_unregister(crtc);
145 drm_debugfs_crtc_remove(crtc);
141 } 146 }
142} 147}
143 148
149static int drm_crtc_crc_init(struct drm_crtc *crtc)
150{
151#ifdef CONFIG_DEBUG_FS
152 spin_lock_init(&crtc->crc.lock);
153 init_waitqueue_head(&crtc->crc.wq);
154 crtc->crc.source = kstrdup("auto", GFP_KERNEL);
155 if (!crtc->crc.source)
156 return -ENOMEM;
157#endif
158 return 0;
159}
160
161static void drm_crtc_crc_fini(struct drm_crtc *crtc)
162{
163#ifdef CONFIG_DEBUG_FS
164 kfree(crtc->crc.source);
165#endif
166}
167
144/** 168/**
145 * drm_crtc_init_with_planes - Initialise a new CRTC object with 169 * drm_crtc_init_with_planes - Initialise a new CRTC object with
146 * specified primary and cursor planes. 170 * specified primary and cursor planes.
@@ -210,6 +234,12 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
210 if (cursor) 234 if (cursor)
211 cursor->possible_crtcs = 1 << drm_crtc_index(crtc); 235 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
212 236
237 ret = drm_crtc_crc_init(crtc);
238 if (ret) {
239 drm_mode_object_unregister(dev, &crtc->base);
240 return ret;
241 }
242
213 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { 243 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
214 drm_object_attach_property(&crtc->base, config->prop_active, 0); 244 drm_object_attach_property(&crtc->base, config->prop_active, 0);
215 drm_object_attach_property(&crtc->base, config->prop_mode_id, 0); 245 drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
@@ -236,6 +266,8 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
236 * the indices on the drm_crtc after us in the crtc_list. 266 * the indices on the drm_crtc after us in the crtc_list.
237 */ 267 */
238 268
269 drm_crtc_crc_fini(crtc);
270
239 kfree(crtc->gamma_store); 271 kfree(crtc->gamma_store);
240 crtc->gamma_store = NULL; 272 crtc->gamma_store = NULL;
241 273
@@ -695,8 +727,7 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
695 drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay); 727 drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
696 728
697 if (crtc->state && 729 if (crtc->state &&
698 crtc->primary->state->rotation & (DRM_ROTATE_90 | 730 drm_rotation_90_or_270(crtc->primary->state->rotation))
699 DRM_ROTATE_270))
700 swap(hdisplay, vdisplay); 731 swap(hdisplay, vdisplay);
701 732
702 return drm_framebuffer_check_src_coords(x << 16, y << 16, 733 return drm_framebuffer_check_src_coords(x << 16, y << 16,
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 1205790ed960..800055c39cdb 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -415,5 +415,37 @@ void drm_debugfs_connector_remove(struct drm_connector *connector)
415 connector->debugfs_entry = NULL; 415 connector->debugfs_entry = NULL;
416} 416}
417 417
418#endif /* CONFIG_DEBUG_FS */ 418int drm_debugfs_crtc_add(struct drm_crtc *crtc)
419{
420 struct drm_minor *minor = crtc->dev->primary;
421 struct dentry *root;
422 char *name;
423
424 name = kasprintf(GFP_KERNEL, "crtc-%d", crtc->index);
425 if (!name)
426 return -ENOMEM;
427
428 root = debugfs_create_dir(name, minor->debugfs_root);
429 kfree(name);
430 if (!root)
431 return -ENOMEM;
432
433 crtc->debugfs_entry = root;
434
435 if (drm_debugfs_crtc_crc_add(crtc))
436 goto error;
419 437
438 return 0;
439
440error:
441 drm_debugfs_crtc_remove(crtc);
442 return -ENOMEM;
443}
444
445void drm_debugfs_crtc_remove(struct drm_crtc *crtc)
446{
447 debugfs_remove_recursive(crtc->debugfs_entry);
448 crtc->debugfs_entry = NULL;
449}
450
451#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c
new file mode 100644
index 000000000000..00e771fb7df2
--- /dev/null
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -0,0 +1,352 @@
1/*
2 * Copyright © 2008 Intel Corporation
3 * Copyright © 2016 Collabora Ltd
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * Based on code from the i915 driver.
25 * Original author: Damien Lespiau <damien.lespiau@intel.com>
26 *
27 */
28
29#include <linux/circ_buf.h>
30#include <linux/ctype.h>
31#include <linux/debugfs.h>
32#include <drm/drmP.h>
33#include "drm_internal.h"
34
35/**
36 * DOC: CRC ABI
37 *
38 * DRM device drivers can provide to userspace CRC information of each frame as
39 * it reached a given hardware component (a "source").
40 *
41 * Userspace can control generation of CRCs in a given CRTC by writing to the
42 * file dri/0/crtc-N/crc/control in debugfs, with N being the index of the CRTC.
43 * Accepted values are source names (which are driver-specific) and the "auto"
44 * keyword, which will let the driver select a default source of frame CRCs
45 * for this CRTC.
46 *
47 * Once frame CRC generation is enabled, userspace can capture them by reading
48 * the dri/0/crtc-N/crc/data file. Each line in that file contains the frame
49 * number in the first field and then a number of unsigned integer fields
50 * containing the CRC data. Fields are separated by a single space and the number
51 * of CRC fields is source-specific.
52 *
53 * Note that though in some cases the CRC is computed in a specified way and on
54 * the frame contents as supplied by userspace (eDP 1.3), in general the CRC
55 * computation is performed in an unspecified way and on frame contents that have
56 * been already processed in also an unspecified way and thus userspace cannot
57 * rely on being able to generate matching CRC values for the frame contents that
58 * it submits. In this general case, the maximum userspace can do is to compare
59 * the reported CRCs of frames that should have the same contents.
60 */
61
62static int crc_control_show(struct seq_file *m, void *data)
63{
64 struct drm_crtc *crtc = m->private;
65
66 seq_printf(m, "%s\n", crtc->crc.source);
67
68 return 0;
69}
70
71static int crc_control_open(struct inode *inode, struct file *file)
72{
73 struct drm_crtc *crtc = inode->i_private;
74
75 return single_open(file, crc_control_show, crtc);
76}
77
78static ssize_t crc_control_write(struct file *file, const char __user *ubuf,
79 size_t len, loff_t *offp)
80{
81 struct seq_file *m = file->private_data;
82 struct drm_crtc *crtc = m->private;
83 struct drm_crtc_crc *crc = &crtc->crc;
84 char *source;
85
86 if (len == 0)
87 return 0;
88
89 if (len > PAGE_SIZE - 1) {
90 DRM_DEBUG_KMS("Expected < %lu bytes into crtc crc control\n",
91 PAGE_SIZE);
92 return -E2BIG;
93 }
94
95 source = memdup_user_nul(ubuf, len);
96 if (IS_ERR(source))
97 return PTR_ERR(source);
98
99 if (source[len] == '\n')
100 source[len] = '\0';
101
102 spin_lock_irq(&crc->lock);
103
104 if (crc->opened) {
105 spin_unlock_irq(&crc->lock);
106 kfree(source);
107 return -EBUSY;
108 }
109
110 kfree(crc->source);
111 crc->source = source;
112
113 spin_unlock_irq(&crc->lock);
114
115 *offp += len;
116 return len;
117}
118
119static const struct file_operations drm_crtc_crc_control_fops = {
120 .owner = THIS_MODULE,
121 .open = crc_control_open,
122 .read = seq_read,
123 .llseek = seq_lseek,
124 .release = single_release,
125 .write = crc_control_write
126};
127
128static int crtc_crc_open(struct inode *inode, struct file *filep)
129{
130 struct drm_crtc *crtc = inode->i_private;
131 struct drm_crtc_crc *crc = &crtc->crc;
132 struct drm_crtc_crc_entry *entries = NULL;
133 size_t values_cnt;
134 int ret;
135
136 if (crc->opened)
137 return -EBUSY;
138
139 ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt);
140 if (ret)
141 return ret;
142
143 if (WARN_ON(values_cnt > DRM_MAX_CRC_NR)) {
144 ret = -EINVAL;
145 goto err_disable;
146 }
147
148 if (WARN_ON(values_cnt == 0)) {
149 ret = -EINVAL;
150 goto err_disable;
151 }
152
153 entries = kcalloc(DRM_CRC_ENTRIES_NR, sizeof(*entries), GFP_KERNEL);
154 if (!entries) {
155 ret = -ENOMEM;
156 goto err_disable;
157 }
158
159 spin_lock_irq(&crc->lock);
160 crc->entries = entries;
161 crc->values_cnt = values_cnt;
162 crc->opened = true;
163 spin_unlock_irq(&crc->lock);
164
165 return 0;
166
167err_disable:
168 crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
169 return ret;
170}
171
172static int crtc_crc_release(struct inode *inode, struct file *filep)
173{
174 struct drm_crtc *crtc = filep->f_inode->i_private;
175 struct drm_crtc_crc *crc = &crtc->crc;
176 size_t values_cnt;
177
178 spin_lock_irq(&crc->lock);
179 kfree(crc->entries);
180 crc->entries = NULL;
181 crc->head = 0;
182 crc->tail = 0;
183 crc->values_cnt = 0;
184 crc->opened = false;
185 spin_unlock_irq(&crc->lock);
186
187 crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
188
189 return 0;
190}
191
192static int crtc_crc_data_count(struct drm_crtc_crc *crc)
193{
194 assert_spin_locked(&crc->lock);
195 return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR);
196}
197
198/*
199 * 1 frame field of 10 chars plus a number of CRC fields of 10 chars each, space
200 * separated, with a newline at the end and null-terminated.
201 */
202#define LINE_LEN(values_cnt) (10 + 11 * values_cnt + 1 + 1)
203#define MAX_LINE_LEN (LINE_LEN(DRM_MAX_CRC_NR))
204
205static ssize_t crtc_crc_read(struct file *filep, char __user *user_buf,
206 size_t count, loff_t *pos)
207{
208 struct drm_crtc *crtc = filep->f_inode->i_private;
209 struct drm_crtc_crc *crc = &crtc->crc;
210 struct drm_crtc_crc_entry *entry;
211 char buf[MAX_LINE_LEN];
212 int ret, i;
213
214 spin_lock_irq(&crc->lock);
215
216 if (!crc->source) {
217 spin_unlock_irq(&crc->lock);
218 return 0;
219 }
220
221 /* Nothing to read? */
222 while (crtc_crc_data_count(crc) == 0) {
223 if (filep->f_flags & O_NONBLOCK) {
224 spin_unlock_irq(&crc->lock);
225 return -EAGAIN;
226 }
227
228 ret = wait_event_interruptible_lock_irq(crc->wq,
229 crtc_crc_data_count(crc),
230 crc->lock);
231 if (ret) {
232 spin_unlock_irq(&crc->lock);
233 return ret;
234 }
235 }
236
237 /* We know we have an entry to be read */
238 entry = &crc->entries[crc->tail];
239
240 if (count < LINE_LEN(crc->values_cnt)) {
241 spin_unlock_irq(&crc->lock);
242 return -EINVAL;
243 }
244
245 BUILD_BUG_ON_NOT_POWER_OF_2(DRM_CRC_ENTRIES_NR);
246 crc->tail = (crc->tail + 1) & (DRM_CRC_ENTRIES_NR - 1);
247
248 spin_unlock_irq(&crc->lock);
249
250 if (entry->has_frame_counter)
251 sprintf(buf, "0x%08x", entry->frame);
252 else
253 sprintf(buf, "XXXXXXXXXX");
254
255 for (i = 0; i < crc->values_cnt; i++)
256 sprintf(buf + 10 + i * 11, " 0x%08x", entry->crcs[i]);
257 sprintf(buf + 10 + crc->values_cnt * 11, "\n");
258
259 if (copy_to_user(user_buf, buf, LINE_LEN(crc->values_cnt)))
260 return -EFAULT;
261
262 return LINE_LEN(crc->values_cnt);
263}
264
265static const struct file_operations drm_crtc_crc_data_fops = {
266 .owner = THIS_MODULE,
267 .open = crtc_crc_open,
268 .read = crtc_crc_read,
269 .release = crtc_crc_release,
270};
271
272/**
273 * drm_debugfs_crtc_crc_add - Add files to debugfs for capture of frame CRCs
274 * @crtc: CRTC to whom the frames will belong
275 *
276 * Adds files to debugfs directory that allows userspace to control the
277 * generation of frame CRCs and to read them.
278 *
279 * Returns:
280 * Zero on success, error code on failure.
281 */
282int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc)
283{
284 struct dentry *crc_ent, *ent;
285
286 if (!crtc->funcs->set_crc_source)
287 return 0;
288
289 crc_ent = debugfs_create_dir("crc", crtc->debugfs_entry);
290 if (!crc_ent)
291 return -ENOMEM;
292
293 ent = debugfs_create_file("control", S_IRUGO, crc_ent, crtc,
294 &drm_crtc_crc_control_fops);
295 if (!ent)
296 goto error;
297
298 ent = debugfs_create_file("data", S_IRUGO, crc_ent, crtc,
299 &drm_crtc_crc_data_fops);
300 if (!ent)
301 goto error;
302
303 return 0;
304
305error:
306 debugfs_remove_recursive(crc_ent);
307
308 return -ENOMEM;
309}
310
311/**
312 * drm_crtc_add_crc_entry - Add entry with CRC information for a frame
313 * @crtc: CRTC to which the frame belongs
314 * @has_frame: whether this entry has a frame number to go with
315 * @frame: number of the frame these CRCs are about
316 * @crcs: array of CRC values, with length matching #drm_crtc_crc.values_cnt
317 *
318 * For each frame, the driver polls the source of CRCs for new data and calls
319 * this function to add them to the buffer from where userspace reads.
320 */
321int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,
322 uint32_t frame, uint32_t *crcs)
323{
324 struct drm_crtc_crc *crc = &crtc->crc;
325 struct drm_crtc_crc_entry *entry;
326 int head, tail;
327
328 assert_spin_locked(&crc->lock);
329
330 /* Caller may not have noticed yet that userspace has stopped reading */
331 if (!crc->opened)
332 return -EINVAL;
333
334 head = crc->head;
335 tail = crc->tail;
336
337 if (CIRC_SPACE(head, tail, DRM_CRC_ENTRIES_NR) < 1) {
338 DRM_ERROR("Overflow of CRC buffer, userspace reads too slow.\n");
339 return -ENOBUFS;
340 }
341
342 entry = &crc->entries[head];
343 entry->frame = frame;
344 entry->has_frame_counter = has_frame;
345 memcpy(&entry->crcs, crcs, sizeof(*crcs) * crc->values_cnt);
346
347 head = (head + 1) & (DRM_CRC_ENTRIES_NR - 1);
348 crc->head = head;
349
350 return 0;
351}
352EXPORT_SYMBOL_GPL(drm_crtc_add_crc_entry);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index ec77bd3e1f08..95de47ba1e77 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1282,20 +1282,20 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
1282 void *data) 1282 void *data)
1283{ 1283{
1284 int i, j = 0, valid_extensions = 0; 1284 int i, j = 0, valid_extensions = 0;
1285 u8 *block, *new; 1285 u8 *edid, *new;
1286 bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS); 1286 bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
1287 1287
1288 if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) 1288 if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
1289 return NULL; 1289 return NULL;
1290 1290
1291 /* base block fetch */ 1291 /* base block fetch */
1292 for (i = 0; i < 4; i++) { 1292 for (i = 0; i < 4; i++) {
1293 if (get_edid_block(data, block, 0, EDID_LENGTH)) 1293 if (get_edid_block(data, edid, 0, EDID_LENGTH))
1294 goto out; 1294 goto out;
1295 if (drm_edid_block_valid(block, 0, print_bad_edid, 1295 if (drm_edid_block_valid(edid, 0, print_bad_edid,
1296 &connector->edid_corrupt)) 1296 &connector->edid_corrupt))
1297 break; 1297 break;
1298 if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) { 1298 if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
1299 connector->null_edid_counter++; 1299 connector->null_edid_counter++;
1300 goto carp; 1300 goto carp;
1301 } 1301 }
@@ -1304,24 +1304,22 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
1304 goto carp; 1304 goto carp;
1305 1305
1306 /* if there's no extensions, we're done */ 1306 /* if there's no extensions, we're done */
1307 if (block[0x7e] == 0) 1307 if (edid[0x7e] == 0)
1308 return (struct edid *)block; 1308 return (struct edid *)edid;
1309 1309
1310 new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); 1310 new = krealloc(edid, (edid[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
1311 if (!new) 1311 if (!new)
1312 goto out; 1312 goto out;
1313 block = new; 1313 edid = new;
1314
1315 for (j = 1; j <= edid[0x7e]; j++) {
1316 u8 *block = edid + (valid_extensions + 1) * EDID_LENGTH;
1314 1317
1315 for (j = 1; j <= block[0x7e]; j++) {
1316 for (i = 0; i < 4; i++) { 1318 for (i = 0; i < 4; i++) {
1317 if (get_edid_block(data, 1319 if (get_edid_block(data, block, j, EDID_LENGTH))
1318 block + (valid_extensions + 1) * EDID_LENGTH,
1319 j, EDID_LENGTH))
1320 goto out; 1320 goto out;
1321 if (drm_edid_block_valid(block + (valid_extensions + 1) 1321 if (drm_edid_block_valid(block, j,
1322 * EDID_LENGTH, j, 1322 print_bad_edid, NULL)) {
1323 print_bad_edid,
1324 NULL)) {
1325 valid_extensions++; 1323 valid_extensions++;
1326 break; 1324 break;
1327 } 1325 }
@@ -1336,16 +1334,16 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
1336 } 1334 }
1337 } 1335 }
1338 1336
1339 if (valid_extensions != block[0x7e]) { 1337 if (valid_extensions != edid[0x7e]) {
1340 block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; 1338 edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
1341 block[0x7e] = valid_extensions; 1339 edid[0x7e] = valid_extensions;
1342 new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); 1340 new = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
1343 if (!new) 1341 if (!new)
1344 goto out; 1342 goto out;
1345 block = new; 1343 edid = new;
1346 } 1344 }
1347 1345
1348 return (struct edid *)block; 1346 return (struct edid *)edid;
1349 1347
1350carp: 1348carp:
1351 if (print_bad_edid) { 1349 if (print_bad_edid) {
@@ -1355,7 +1353,7 @@ carp:
1355 connector->bad_edid_counter++; 1353 connector->bad_edid_counter++;
1356 1354
1357out: 1355out:
1358 kfree(block); 1356 kfree(edid);
1359 return NULL; 1357 return NULL;
1360} 1358}
1361EXPORT_SYMBOL_GPL(drm_do_get_edid); 1359EXPORT_SYMBOL_GPL(drm_do_get_edid);
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 1fd6eac1400c..4c6664407bfb 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -176,20 +176,20 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
176 struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd, 176 struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd,
177 const struct drm_framebuffer_funcs *funcs) 177 const struct drm_framebuffer_funcs *funcs)
178{ 178{
179 const struct drm_format_info *info;
179 struct drm_fb_cma *fb_cma; 180 struct drm_fb_cma *fb_cma;
180 struct drm_gem_cma_object *objs[4]; 181 struct drm_gem_cma_object *objs[4];
181 struct drm_gem_object *obj; 182 struct drm_gem_object *obj;
182 unsigned int hsub;
183 unsigned int vsub;
184 int ret; 183 int ret;
185 int i; 184 int i;
186 185
187 hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format); 186 info = drm_format_info(mode_cmd->pixel_format);
188 vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format); 187 if (!info)
188 return ERR_PTR(-EINVAL);
189 189
190 for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) { 190 for (i = 0; i < info->num_planes; i++) {
191 unsigned int width = mode_cmd->width / (i ? hsub : 1); 191 unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
192 unsigned int height = mode_cmd->height / (i ? vsub : 1); 192 unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
193 unsigned int min_size; 193 unsigned int min_size;
194 194
195 obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); 195 obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
@@ -200,7 +200,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
200 } 200 }
201 201
202 min_size = (height - 1) * mode_cmd->pitches[i] 202 min_size = (height - 1) * mode_cmd->pitches[i]
203 + width * drm_format_plane_cpp(mode_cmd->pixel_format, i) 203 + width * info->cpp[i]
204 + mode_cmd->offsets[i]; 204 + mode_cmd->offsets[i];
205 205
206 if (obj->size < min_size) { 206 if (obj->size < min_size) {
@@ -269,12 +269,15 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
269static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m) 269static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
270{ 270{
271 struct drm_fb_cma *fb_cma = to_fb_cma(fb); 271 struct drm_fb_cma *fb_cma = to_fb_cma(fb);
272 int i, n = drm_format_num_planes(fb->pixel_format); 272 const struct drm_format_info *info;
273 int i;
273 274
274 seq_printf(m, "fb: %dx%d@%4.4s\n", fb->width, fb->height, 275 seq_printf(m, "fb: %dx%d@%4.4s\n", fb->width, fb->height,
275 (char *)&fb->pixel_format); 276 (char *)&fb->pixel_format);
276 277
277 for (i = 0; i < n; i++) { 278 info = drm_format_info(fb->pixel_format);
279
280 for (i = 0; i < info->num_planes; i++) {
278 seq_printf(m, " %d: offset=%d pitch=%d, obj: ", 281 seq_printf(m, " %d: offset=%d pitch=%d, obj: ",
279 i, fb->offsets[i], fb->pitches[i]); 282 i, fb->offsets[i], fb->pitches[i]);
280 drm_gem_cma_describe(fb_cma->obj[i], m); 283 drm_gem_cma_describe(fb_cma->obj[i], m);
@@ -557,7 +560,8 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_init);
557void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma) 560void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma)
558{ 561{
559 drm_fb_helper_unregister_fbi(&fbdev_cma->fb_helper); 562 drm_fb_helper_unregister_fbi(&fbdev_cma->fb_helper);
560 drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev); 563 if (fbdev_cma->fb_helper.fbdev)
564 drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev);
561 drm_fb_helper_release_fbi(&fbdev_cma->fb_helper); 565 drm_fb_helper_release_fbi(&fbdev_cma->fb_helper);
562 566
563 if (fbdev_cma->fb) { 567 if (fbdev_cma->fb) {
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 03414bde1f15..e0d428f9d1cb 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -367,9 +367,7 @@ fail:
367 if (ret == -EDEADLK) 367 if (ret == -EDEADLK)
368 goto backoff; 368 goto backoff;
369 369
370 if (ret != 0) 370 drm_atomic_state_put(state);
371 drm_atomic_state_free(state);
372
373 return ret; 371 return ret;
374 372
375backoff: 373backoff:
@@ -394,7 +392,11 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
394 if (plane->type != DRM_PLANE_TYPE_PRIMARY) 392 if (plane->type != DRM_PLANE_TYPE_PRIMARY)
395 drm_plane_force_disable(plane); 393 drm_plane_force_disable(plane);
396 394
397 if (dev->mode_config.rotation_property) { 395 if (plane->rotation_property) {
396 drm_mode_plane_set_obj_prop(plane,
397 plane->rotation_property,
398 DRM_ROTATE_0);
399 } else if (dev->mode_config.rotation_property) {
398 drm_mode_plane_set_obj_prop(plane, 400 drm_mode_plane_set_obj_prop(plane,
399 dev->mode_config.rotation_property, 401 dev->mode_config.rotation_property,
400 DRM_ROTATE_0); 402 DRM_ROTATE_0);
@@ -1211,11 +1213,14 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
1211 if (var->pixclock != 0 || in_dbg_master()) 1213 if (var->pixclock != 0 || in_dbg_master())
1212 return -EINVAL; 1214 return -EINVAL;
1213 1215
1214 /* Need to resize the fb object !!! */ 1216 /*
1215 if (var->bits_per_pixel > fb->bits_per_pixel || 1217 * Changes struct fb_var_screeninfo are currently not pushed back
1216 var->xres > fb->width || var->yres > fb->height || 1218 * to KMS, hence fail if different settings are requested.
1217 var->xres_virtual > fb->width || var->yres_virtual > fb->height) { 1219 */
1218 DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb " 1220 if (var->bits_per_pixel != fb->bits_per_pixel ||
1221 var->xres != fb->width || var->yres != fb->height ||
1222 var->xres_virtual != fb->width || var->yres_virtual != fb->height) {
1223 DRM_DEBUG("fb userspace requested width/height/bpp different than current fb "
1219 "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n", 1224 "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n",
1220 var->xres, var->yres, var->bits_per_pixel, 1225 var->xres, var->yres, var->bits_per_pixel,
1221 var->xres_virtual, var->yres_virtual, 1226 var->xres_virtual, var->yres_virtual,
@@ -1361,16 +1366,13 @@ retry:
1361 info->var.xoffset = var->xoffset; 1366 info->var.xoffset = var->xoffset;
1362 info->var.yoffset = var->yoffset; 1367 info->var.yoffset = var->yoffset;
1363 1368
1364
1365fail: 1369fail:
1366 drm_atomic_clean_old_fb(dev, plane_mask, ret); 1370 drm_atomic_clean_old_fb(dev, plane_mask, ret);
1367 1371
1368 if (ret == -EDEADLK) 1372 if (ret == -EDEADLK)
1369 goto backoff; 1373 goto backoff;
1370 1374
1371 if (ret != 0) 1375 drm_atomic_state_put(state);
1372 drm_atomic_state_free(state);
1373
1374 return ret; 1376 return ret;
1375 1377
1376backoff: 1378backoff:
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index e84faecf5225..8bed5f459182 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -663,6 +663,10 @@ void drm_event_cancel_free(struct drm_device *dev,
663 list_del(&p->pending_link); 663 list_del(&p->pending_link);
664 } 664 }
665 spin_unlock_irqrestore(&dev->event_lock, flags); 665 spin_unlock_irqrestore(&dev->event_lock, flags);
666
667 if (p->fence)
668 fence_put(p->fence);
669
666 kfree(p); 670 kfree(p);
667} 671}
668EXPORT_SYMBOL(drm_event_cancel_free); 672EXPORT_SYMBOL(drm_event_cancel_free);
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 29c56b4331e0..cbb8b77c363c 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -102,83 +102,105 @@ char *drm_get_format_name(uint32_t format)
102} 102}
103EXPORT_SYMBOL(drm_get_format_name); 103EXPORT_SYMBOL(drm_get_format_name);
104 104
105/*
106 * Internal function to query information for a given format. See
107 * drm_format_info() for the public API.
108 */
109const struct drm_format_info *__drm_format_info(u32 format)
110{
111 static const struct drm_format_info formats[] = {
112 { .format = DRM_FORMAT_C8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
113 { .format = DRM_FORMAT_RGB332, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
114 { .format = DRM_FORMAT_BGR233, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
115 { .format = DRM_FORMAT_XRGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
116 { .format = DRM_FORMAT_XBGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
117 { .format = DRM_FORMAT_RGBX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
118 { .format = DRM_FORMAT_BGRX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
119 { .format = DRM_FORMAT_ARGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
120 { .format = DRM_FORMAT_ABGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
121 { .format = DRM_FORMAT_RGBA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
122 { .format = DRM_FORMAT_BGRA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
123 { .format = DRM_FORMAT_XRGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
124 { .format = DRM_FORMAT_XBGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
125 { .format = DRM_FORMAT_RGBX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
126 { .format = DRM_FORMAT_BGRX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
127 { .format = DRM_FORMAT_ARGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
128 { .format = DRM_FORMAT_ABGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
129 { .format = DRM_FORMAT_RGBA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
130 { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
131 { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
132 { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
133 { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
134 { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
135 { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
136 { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
137 { .format = DRM_FORMAT_RGBX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
138 { .format = DRM_FORMAT_BGRX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
139 { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
140 { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
141 { .format = DRM_FORMAT_RGBX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
142 { .format = DRM_FORMAT_BGRX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
143 { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
144 { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
145 { .format = DRM_FORMAT_RGBA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
146 { .format = DRM_FORMAT_BGRA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
147 { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
148 { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
149 { .format = DRM_FORMAT_RGBA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
150 { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
151 { .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4 },
152 { .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4 },
153 { .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1 },
154 { .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1 },
155 { .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2 },
156 { .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2 },
157 { .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1 },
158 { .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1 },
159 { .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1 },
160 { .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1 },
161 { .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
162 { .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
163 { .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1 },
164 { .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1 },
165 { .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1 },
166 { .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1 },
167 { .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
168 { .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
169 { .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
170 { .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
171 { .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
172 };
173
174 unsigned int i;
175
176 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
177 if (formats[i].format == format)
178 return &formats[i];
179 }
180
181 return NULL;
182}
183
105/** 184/**
106 * drm_fb_get_bpp_depth - get the bpp/depth values for format 185 * drm_format_info - query information for a given format
107 * @format: pixel format (DRM_FORMAT_*) 186 * @format: pixel format (DRM_FORMAT_*)
108 * @depth: storage for the depth value
109 * @bpp: storage for the bpp value
110 * 187 *
111 * This only supports RGB formats here for compat with code that doesn't use 188 * The caller should only pass a supported pixel format to this function.
112 * pixel formats directly yet. 189 * Unsupported pixel formats will generate a warning in the kernel log.
190 *
191 * Returns:
192 * The instance of struct drm_format_info that describes the pixel format, or
193 * NULL if the format is unsupported.
113 */ 194 */
114void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, 195const struct drm_format_info *drm_format_info(u32 format)
115 int *bpp)
116{ 196{
117 char *format_name; 197 const struct drm_format_info *info;
118 198
119 switch (format) { 199 info = __drm_format_info(format);
120 case DRM_FORMAT_C8: 200 WARN_ON(!info);
121 case DRM_FORMAT_RGB332: 201 return info;
122 case DRM_FORMAT_BGR233:
123 *depth = 8;
124 *bpp = 8;
125 break;
126 case DRM_FORMAT_XRGB1555:
127 case DRM_FORMAT_XBGR1555:
128 case DRM_FORMAT_RGBX5551:
129 case DRM_FORMAT_BGRX5551:
130 case DRM_FORMAT_ARGB1555:
131 case DRM_FORMAT_ABGR1555:
132 case DRM_FORMAT_RGBA5551:
133 case DRM_FORMAT_BGRA5551:
134 *depth = 15;
135 *bpp = 16;
136 break;
137 case DRM_FORMAT_RGB565:
138 case DRM_FORMAT_BGR565:
139 *depth = 16;
140 *bpp = 16;
141 break;
142 case DRM_FORMAT_RGB888:
143 case DRM_FORMAT_BGR888:
144 *depth = 24;
145 *bpp = 24;
146 break;
147 case DRM_FORMAT_XRGB8888:
148 case DRM_FORMAT_XBGR8888:
149 case DRM_FORMAT_RGBX8888:
150 case DRM_FORMAT_BGRX8888:
151 *depth = 24;
152 *bpp = 32;
153 break;
154 case DRM_FORMAT_XRGB2101010:
155 case DRM_FORMAT_XBGR2101010:
156 case DRM_FORMAT_RGBX1010102:
157 case DRM_FORMAT_BGRX1010102:
158 case DRM_FORMAT_ARGB2101010:
159 case DRM_FORMAT_ABGR2101010:
160 case DRM_FORMAT_RGBA1010102:
161 case DRM_FORMAT_BGRA1010102:
162 *depth = 30;
163 *bpp = 32;
164 break;
165 case DRM_FORMAT_ARGB8888:
166 case DRM_FORMAT_ABGR8888:
167 case DRM_FORMAT_RGBA8888:
168 case DRM_FORMAT_BGRA8888:
169 *depth = 32;
170 *bpp = 32;
171 break;
172 default:
173 format_name = drm_get_format_name(format);
174 DRM_DEBUG_KMS("unsupported pixel format %s\n", format_name);
175 kfree(format_name);
176 *depth = 0;
177 *bpp = 0;
178 break;
179 }
180} 202}
181EXPORT_SYMBOL(drm_fb_get_bpp_depth); 203EXPORT_SYMBOL(drm_format_info);
182 204
183/** 205/**
184 * drm_format_num_planes - get the number of planes for format 206 * drm_format_num_planes - get the number of planes for format
@@ -189,28 +211,10 @@ EXPORT_SYMBOL(drm_fb_get_bpp_depth);
189 */ 211 */
190int drm_format_num_planes(uint32_t format) 212int drm_format_num_planes(uint32_t format)
191{ 213{
192 switch (format) { 214 const struct drm_format_info *info;
193 case DRM_FORMAT_YUV410: 215
194 case DRM_FORMAT_YVU410: 216 info = drm_format_info(format);
195 case DRM_FORMAT_YUV411: 217 return info ? info->num_planes : 1;
196 case DRM_FORMAT_YVU411:
197 case DRM_FORMAT_YUV420:
198 case DRM_FORMAT_YVU420:
199 case DRM_FORMAT_YUV422:
200 case DRM_FORMAT_YVU422:
201 case DRM_FORMAT_YUV444:
202 case DRM_FORMAT_YVU444:
203 return 3;
204 case DRM_FORMAT_NV12:
205 case DRM_FORMAT_NV21:
206 case DRM_FORMAT_NV16:
207 case DRM_FORMAT_NV61:
208 case DRM_FORMAT_NV24:
209 case DRM_FORMAT_NV42:
210 return 2;
211 default:
212 return 1;
213 }
214} 218}
215EXPORT_SYMBOL(drm_format_num_planes); 219EXPORT_SYMBOL(drm_format_num_planes);
216 220
@@ -224,40 +228,13 @@ EXPORT_SYMBOL(drm_format_num_planes);
224 */ 228 */
225int drm_format_plane_cpp(uint32_t format, int plane) 229int drm_format_plane_cpp(uint32_t format, int plane)
226{ 230{
227 unsigned int depth; 231 const struct drm_format_info *info;
228 int bpp;
229 232
230 if (plane >= drm_format_num_planes(format)) 233 info = drm_format_info(format);
234 if (!info || plane >= info->num_planes)
231 return 0; 235 return 0;
232 236
233 switch (format) { 237 return info->cpp[plane];
234 case DRM_FORMAT_YUYV:
235 case DRM_FORMAT_YVYU:
236 case DRM_FORMAT_UYVY:
237 case DRM_FORMAT_VYUY:
238 return 2;
239 case DRM_FORMAT_NV12:
240 case DRM_FORMAT_NV21:
241 case DRM_FORMAT_NV16:
242 case DRM_FORMAT_NV61:
243 case DRM_FORMAT_NV24:
244 case DRM_FORMAT_NV42:
245 return plane ? 2 : 1;
246 case DRM_FORMAT_YUV410:
247 case DRM_FORMAT_YVU410:
248 case DRM_FORMAT_YUV411:
249 case DRM_FORMAT_YVU411:
250 case DRM_FORMAT_YUV420:
251 case DRM_FORMAT_YVU420:
252 case DRM_FORMAT_YUV422:
253 case DRM_FORMAT_YVU422:
254 case DRM_FORMAT_YUV444:
255 case DRM_FORMAT_YVU444:
256 return 1;
257 default:
258 drm_fb_get_bpp_depth(format, &depth, &bpp);
259 return bpp >> 3;
260 }
261} 238}
262EXPORT_SYMBOL(drm_format_plane_cpp); 239EXPORT_SYMBOL(drm_format_plane_cpp);
263 240
@@ -271,28 +248,10 @@ EXPORT_SYMBOL(drm_format_plane_cpp);
271 */ 248 */
272int drm_format_horz_chroma_subsampling(uint32_t format) 249int drm_format_horz_chroma_subsampling(uint32_t format)
273{ 250{
274 switch (format) { 251 const struct drm_format_info *info;
275 case DRM_FORMAT_YUV411: 252
276 case DRM_FORMAT_YVU411: 253 info = drm_format_info(format);
277 case DRM_FORMAT_YUV410: 254 return info ? info->hsub : 1;
278 case DRM_FORMAT_YVU410:
279 return 4;
280 case DRM_FORMAT_YUYV:
281 case DRM_FORMAT_YVYU:
282 case DRM_FORMAT_UYVY:
283 case DRM_FORMAT_VYUY:
284 case DRM_FORMAT_NV12:
285 case DRM_FORMAT_NV21:
286 case DRM_FORMAT_NV16:
287 case DRM_FORMAT_NV61:
288 case DRM_FORMAT_YUV422:
289 case DRM_FORMAT_YVU422:
290 case DRM_FORMAT_YUV420:
291 case DRM_FORMAT_YVU420:
292 return 2;
293 default:
294 return 1;
295 }
296} 255}
297EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); 256EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
298 257
@@ -306,18 +265,10 @@ EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
306 */ 265 */
307int drm_format_vert_chroma_subsampling(uint32_t format) 266int drm_format_vert_chroma_subsampling(uint32_t format)
308{ 267{
309 switch (format) { 268 const struct drm_format_info *info;
310 case DRM_FORMAT_YUV410: 269
311 case DRM_FORMAT_YVU410: 270 info = drm_format_info(format);
312 return 4; 271 return info ? info->vsub : 1;
313 case DRM_FORMAT_YUV420:
314 case DRM_FORMAT_YVU420:
315 case DRM_FORMAT_NV12:
316 case DRM_FORMAT_NV21:
317 return 2;
318 default:
319 return 1;
320 }
321} 272}
322EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); 273EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
323 274
@@ -332,13 +283,16 @@ EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
332 */ 283 */
333int drm_format_plane_width(int width, uint32_t format, int plane) 284int drm_format_plane_width(int width, uint32_t format, int plane)
334{ 285{
335 if (plane >= drm_format_num_planes(format)) 286 const struct drm_format_info *info;
287
288 info = drm_format_info(format);
289 if (!info || plane >= info->num_planes)
336 return 0; 290 return 0;
337 291
338 if (plane == 0) 292 if (plane == 0)
339 return width; 293 return width;
340 294
341 return width / drm_format_horz_chroma_subsampling(format); 295 return width / info->hsub;
342} 296}
343EXPORT_SYMBOL(drm_format_plane_width); 297EXPORT_SYMBOL(drm_format_plane_width);
344 298
@@ -353,12 +307,15 @@ EXPORT_SYMBOL(drm_format_plane_width);
353 */ 307 */
354int drm_format_plane_height(int height, uint32_t format, int plane) 308int drm_format_plane_height(int height, uint32_t format, int plane)
355{ 309{
356 if (plane >= drm_format_num_planes(format)) 310 const struct drm_format_info *info;
311
312 info = drm_format_info(format);
313 if (!info || plane >= info->num_planes)
357 return 0; 314 return 0;
358 315
359 if (plane == 0) 316 if (plane == 0)
360 return height; 317 return height;
361 318
362 return height / drm_format_vert_chroma_subsampling(format); 319 return height / info->vsub;
363} 320}
364EXPORT_SYMBOL(drm_format_plane_height); 321EXPORT_SYMBOL(drm_format_plane_height);
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 398efd67cb93..49fd7db758e0 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -126,111 +126,33 @@ int drm_mode_addfb(struct drm_device *dev,
126 return 0; 126 return 0;
127} 127}
128 128
129static int format_check(const struct drm_mode_fb_cmd2 *r)
130{
131 uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN;
132 char *format_name;
133
134 switch (format) {
135 case DRM_FORMAT_C8:
136 case DRM_FORMAT_RGB332:
137 case DRM_FORMAT_BGR233:
138 case DRM_FORMAT_XRGB4444:
139 case DRM_FORMAT_XBGR4444:
140 case DRM_FORMAT_RGBX4444:
141 case DRM_FORMAT_BGRX4444:
142 case DRM_FORMAT_ARGB4444:
143 case DRM_FORMAT_ABGR4444:
144 case DRM_FORMAT_RGBA4444:
145 case DRM_FORMAT_BGRA4444:
146 case DRM_FORMAT_XRGB1555:
147 case DRM_FORMAT_XBGR1555:
148 case DRM_FORMAT_RGBX5551:
149 case DRM_FORMAT_BGRX5551:
150 case DRM_FORMAT_ARGB1555:
151 case DRM_FORMAT_ABGR1555:
152 case DRM_FORMAT_RGBA5551:
153 case DRM_FORMAT_BGRA5551:
154 case DRM_FORMAT_RGB565:
155 case DRM_FORMAT_BGR565:
156 case DRM_FORMAT_RGB888:
157 case DRM_FORMAT_BGR888:
158 case DRM_FORMAT_XRGB8888:
159 case DRM_FORMAT_XBGR8888:
160 case DRM_FORMAT_RGBX8888:
161 case DRM_FORMAT_BGRX8888:
162 case DRM_FORMAT_ARGB8888:
163 case DRM_FORMAT_ABGR8888:
164 case DRM_FORMAT_RGBA8888:
165 case DRM_FORMAT_BGRA8888:
166 case DRM_FORMAT_XRGB2101010:
167 case DRM_FORMAT_XBGR2101010:
168 case DRM_FORMAT_RGBX1010102:
169 case DRM_FORMAT_BGRX1010102:
170 case DRM_FORMAT_ARGB2101010:
171 case DRM_FORMAT_ABGR2101010:
172 case DRM_FORMAT_RGBA1010102:
173 case DRM_FORMAT_BGRA1010102:
174 case DRM_FORMAT_YUYV:
175 case DRM_FORMAT_YVYU:
176 case DRM_FORMAT_UYVY:
177 case DRM_FORMAT_VYUY:
178 case DRM_FORMAT_AYUV:
179 case DRM_FORMAT_NV12:
180 case DRM_FORMAT_NV21:
181 case DRM_FORMAT_NV16:
182 case DRM_FORMAT_NV61:
183 case DRM_FORMAT_NV24:
184 case DRM_FORMAT_NV42:
185 case DRM_FORMAT_YUV410:
186 case DRM_FORMAT_YVU410:
187 case DRM_FORMAT_YUV411:
188 case DRM_FORMAT_YVU411:
189 case DRM_FORMAT_YUV420:
190 case DRM_FORMAT_YVU420:
191 case DRM_FORMAT_YUV422:
192 case DRM_FORMAT_YVU422:
193 case DRM_FORMAT_YUV444:
194 case DRM_FORMAT_YVU444:
195 return 0;
196 default:
197 format_name = drm_get_format_name(r->pixel_format);
198 DRM_DEBUG_KMS("invalid pixel format %s\n", format_name);
199 kfree(format_name);
200 return -EINVAL;
201 }
202}
203
204static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) 129static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
205{ 130{
206 int ret, hsub, vsub, num_planes, i; 131 const struct drm_format_info *info;
132 int i;
207 133
208 ret = format_check(r); 134 info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
209 if (ret) { 135 if (!info) {
210 char *format_name = drm_get_format_name(r->pixel_format); 136 char *format_name = drm_get_format_name(r->pixel_format);
211 DRM_DEBUG_KMS("bad framebuffer format %s\n", format_name); 137 DRM_DEBUG_KMS("bad framebuffer format %s\n", format_name);
212 kfree(format_name); 138 kfree(format_name);
213 return ret; 139 return -EINVAL;
214 } 140 }
215 141
216 hsub = drm_format_horz_chroma_subsampling(r->pixel_format); 142 if (r->width == 0 || r->width % info->hsub) {
217 vsub = drm_format_vert_chroma_subsampling(r->pixel_format);
218 num_planes = drm_format_num_planes(r->pixel_format);
219
220 if (r->width == 0 || r->width % hsub) {
221 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width); 143 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
222 return -EINVAL; 144 return -EINVAL;
223 } 145 }
224 146
225 if (r->height == 0 || r->height % vsub) { 147 if (r->height == 0 || r->height % info->vsub) {
226 DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height); 148 DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
227 return -EINVAL; 149 return -EINVAL;
228 } 150 }
229 151
230 for (i = 0; i < num_planes; i++) { 152 for (i = 0; i < info->num_planes; i++) {
231 unsigned int width = r->width / (i != 0 ? hsub : 1); 153 unsigned int width = r->width / (i != 0 ? info->hsub : 1);
232 unsigned int height = r->height / (i != 0 ? vsub : 1); 154 unsigned int height = r->height / (i != 0 ? info->vsub : 1);
233 unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i); 155 unsigned int cpp = info->cpp[i];
234 156
235 if (!r->handles[i]) { 157 if (!r->handles[i]) {
236 DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i); 158 DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
@@ -273,7 +195,7 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
273 } 195 }
274 } 196 }
275 197
276 for (i = num_planes; i < 4; i++) { 198 for (i = info->num_planes; i < 4; i++) {
277 if (r->modifier[i]) { 199 if (r->modifier[i]) {
278 DRM_DEBUG_KMS("non-zero modifier for unused plane %d\n", i); 200 DRM_DEBUG_KMS("non-zero modifier for unused plane %d\n", i);
279 return -EINVAL; 201 return -EINVAL;
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index e66af289a016..abd209863ef4 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -100,6 +100,9 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
100int drm_debugfs_cleanup(struct drm_minor *minor); 100int drm_debugfs_cleanup(struct drm_minor *minor);
101int drm_debugfs_connector_add(struct drm_connector *connector); 101int drm_debugfs_connector_add(struct drm_connector *connector);
102void drm_debugfs_connector_remove(struct drm_connector *connector); 102void drm_debugfs_connector_remove(struct drm_connector *connector);
103int drm_debugfs_crtc_add(struct drm_crtc *crtc);
104void drm_debugfs_crtc_remove(struct drm_crtc *crtc);
105int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc);
103#else 106#else
104static inline int drm_debugfs_init(struct drm_minor *minor, int minor_id, 107static inline int drm_debugfs_init(struct drm_minor *minor, int minor_id,
105 struct dentry *root) 108 struct dentry *root)
@@ -119,4 +122,17 @@ static inline int drm_debugfs_connector_add(struct drm_connector *connector)
119static inline void drm_debugfs_connector_remove(struct drm_connector *connector) 122static inline void drm_debugfs_connector_remove(struct drm_connector *connector)
120{ 123{
121} 124}
125
126static inline int drm_debugfs_crtc_add(struct drm_crtc *crtc)
127{
128 return 0;
129}
130static inline void drm_debugfs_crtc_remove(struct drm_crtc *crtc)
131{
132}
133
134static inline int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc)
135{
136 return 0;
137}
122#endif 138#endif
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index b969a64a1514..48a6167f5e7b 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -952,8 +952,10 @@ static u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
952 u32 vblank_count; 952 u32 vblank_count;
953 unsigned int seq; 953 unsigned int seq;
954 954
955 if (WARN_ON(pipe >= dev->num_crtcs)) 955 if (WARN_ON(pipe >= dev->num_crtcs)) {
956 *vblanktime = (struct timeval) { 0 };
956 return 0; 957 return 0;
958 }
957 959
958 do { 960 do {
959 seq = read_seqbegin(&vblank->seqlock); 961 seq = read_seqbegin(&vblank->seqlock);
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 53f07ac7c174..f64ac86deb84 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -165,6 +165,7 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
165 unsigned int vfieldrate, hperiod; 165 unsigned int vfieldrate, hperiod;
166 int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync; 166 int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync;
167 int interlace; 167 int interlace;
168 u64 tmp;
168 169
169 /* allocate the drm_display_mode structure. If failure, we will 170 /* allocate the drm_display_mode structure. If failure, we will
170 * return directly 171 * return directly
@@ -322,8 +323,11 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
322 drm_mode->vsync_end = drm_mode->vsync_start + vsync; 323 drm_mode->vsync_end = drm_mode->vsync_start + vsync;
323 } 324 }
324 /* 15/13. Find pixel clock frequency (kHz for xf86) */ 325 /* 15/13. Find pixel clock frequency (kHz for xf86) */
325 drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; 326 tmp = drm_mode->htotal; /* perform intermediate calcs in u64 */
326 drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; 327 tmp *= HV_FACTOR * 1000;
328 do_div(tmp, hperiod);
329 tmp -= drm_mode->clock % CVT_CLOCK_STEP;
330 drm_mode->clock = tmp;
327 /* 18/16. Find actual vertical frame frequency */ 331 /* 18/16. Find actual vertical frame frequency */
328 /* ignore - just set the mode flag for interlaced */ 332 /* ignore - just set the mode flag for interlaced */
329 if (interlaced) { 333 if (interlaced) {
@@ -997,6 +1001,7 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
997 mode1->vsync_end == mode2->vsync_end && 1001 mode1->vsync_end == mode2->vsync_end &&
998 mode1->vtotal == mode2->vtotal && 1002 mode1->vtotal == mode2->vtotal &&
999 mode1->vscan == mode2->vscan && 1003 mode1->vscan == mode2->vscan &&
1004 mode1->picture_aspect_ratio == mode2->picture_aspect_ratio &&
1000 (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) == 1005 (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
1001 (mode2->flags & ~DRM_MODE_FLAG_3D_MASK)) 1006 (mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
1002 return true; 1007 return true;
@@ -1499,6 +1504,27 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
1499 out->vrefresh = in->vrefresh; 1504 out->vrefresh = in->vrefresh;
1500 out->flags = in->flags; 1505 out->flags = in->flags;
1501 out->type = in->type; 1506 out->type = in->type;
1507 out->flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
1508
1509 switch (in->picture_aspect_ratio) {
1510 case HDMI_PICTURE_ASPECT_4_3:
1511 out->flags |= DRM_MODE_FLAG_PIC_AR_4_3;
1512 break;
1513 case HDMI_PICTURE_ASPECT_16_9:
1514 out->flags |= DRM_MODE_FLAG_PIC_AR_16_9;
1515 break;
1516 case HDMI_PICTURE_ASPECT_64_27:
1517 out->flags |= DRM_MODE_FLAG_PIC_AR_64_27;
1518 break;
1519 case DRM_MODE_PICTURE_ASPECT_256_135:
1520 out->flags |= DRM_MODE_FLAG_PIC_AR_256_135;
1521 break;
1522 case HDMI_PICTURE_ASPECT_RESERVED:
1523 default:
1524 out->flags |= DRM_MODE_FLAG_PIC_AR_NONE;
1525 break;
1526 }
1527
1502 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 1528 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1503 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 1529 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1504} 1530}
@@ -1544,6 +1570,27 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
1544 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 1570 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1545 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 1571 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1546 1572
1573 /* Clearing picture aspect ratio bits from out flags */
1574 out->flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
1575
1576 switch (in->flags & DRM_MODE_FLAG_PIC_AR_MASK) {
1577 case DRM_MODE_FLAG_PIC_AR_4_3:
1578 out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_4_3;
1579 break;
1580 case DRM_MODE_FLAG_PIC_AR_16_9:
1581 out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_16_9;
1582 break;
1583 case DRM_MODE_FLAG_PIC_AR_64_27:
1584 out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_64_27;
1585 break;
1586 case DRM_MODE_FLAG_PIC_AR_256_135:
1587 out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_256_135;
1588 break;
1589 default:
1590 out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
1591 break;
1592 }
1593
1547 out->status = drm_mode_validate_basic(out); 1594 out->status = drm_mode_validate_basic(out);
1548 if (out->status != MODE_OK) 1595 if (out->status != MODE_OK)
1549 goto out; 1596 goto out;
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index 1d45738f8f98..2544dfe7354c 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -70,8 +70,23 @@ EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
70void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, 70void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
71 const struct drm_mode_fb_cmd2 *mode_cmd) 71 const struct drm_mode_fb_cmd2 *mode_cmd)
72{ 72{
73 const struct drm_format_info *info;
73 int i; 74 int i;
74 75
76 info = drm_format_info(mode_cmd->pixel_format);
77 if (!info || !info->depth) {
78 char *format_name = drm_get_format_name(mode_cmd->pixel_format);
79
80 DRM_DEBUG_KMS("non-RGB pixel format %s\n", format_name);
81 kfree(format_name);
82
83 fb->depth = 0;
84 fb->bits_per_pixel = 0;
85 } else {
86 fb->depth = info->depth;
87 fb->bits_per_pixel = info->cpp[0] * 8;
88 }
89
75 fb->width = mode_cmd->width; 90 fb->width = mode_cmd->width;
76 fb->height = mode_cmd->height; 91 fb->height = mode_cmd->height;
77 for (i = 0; i < 4; i++) { 92 for (i = 0; i < 4; i++) {
@@ -79,8 +94,6 @@ void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
79 fb->offsets[i] = mode_cmd->offsets[i]; 94 fb->offsets[i] = mode_cmd->offsets[i];
80 fb->modifier[i] = mode_cmd->modifier[i]; 95 fb->modifier[i] = mode_cmd->modifier[i];
81 } 96 }
82 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
83 &fb->bits_per_pixel);
84 fb->pixel_format = mode_cmd->pixel_format; 97 fb->pixel_format = mode_cmd->pixel_format;
85 fb->flags = mode_cmd->flags; 98 fb->flags = mode_cmd->flags;
86} 99}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index 0370b842d9cc..3755ef935af4 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -409,20 +409,16 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
409 struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); 409 struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
410 struct drm_device *dev = obj->dev; 410 struct drm_device *dev = obj->dev;
411 bool write = !!(op & ETNA_PREP_WRITE); 411 bool write = !!(op & ETNA_PREP_WRITE);
412 int ret; 412 unsigned long remain =
413 413 op & ETNA_PREP_NOSYNC ? 0 : etnaviv_timeout_to_jiffies(timeout);
414 if (op & ETNA_PREP_NOSYNC) { 414 long lret;
415 if (!reservation_object_test_signaled_rcu(etnaviv_obj->resv, 415
416 write)) 416 lret = reservation_object_wait_timeout_rcu(etnaviv_obj->resv,
417 return -EBUSY; 417 write, true, remain);
418 } else { 418 if (lret < 0)
419 unsigned long remain = etnaviv_timeout_to_jiffies(timeout); 419 return lret;
420 420 else if (lret == 0)
421 ret = reservation_object_wait_timeout_rcu(etnaviv_obj->resv, 421 return remain == 0 ? -EBUSY : -ETIMEDOUT;
422 write, true, remain);
423 if (ret <= 0)
424 return ret == 0 ? -ETIMEDOUT : ret;
425 }
426 422
427 if (etnaviv_obj->flags & ETNA_BO_CACHED) { 423 if (etnaviv_obj->flags & ETNA_BO_CACHED) {
428 if (!etnaviv_obj->sgt) { 424 if (!etnaviv_obj->sgt) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index def78c8c1780..4a21a745c373 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -69,7 +69,7 @@ static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit)
69 69
70 drm_atomic_helper_cleanup_planes(dev, state); 70 drm_atomic_helper_cleanup_planes(dev, state);
71 71
72 drm_atomic_state_free(state); 72 drm_atomic_state_put(state);
73 73
74 spin_lock(&priv->lock); 74 spin_lock(&priv->lock);
75 priv->pending &= ~commit->crtcs; 75 priv->pending &= ~commit->crtcs;
@@ -254,6 +254,7 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
254 254
255 drm_atomic_helper_swap_state(state, true); 255 drm_atomic_helper_swap_state(state, true);
256 256
257 drm_atomic_state_get(state);
257 if (nonblock) 258 if (nonblock)
258 schedule_work(&commit->work); 259 schedule_work(&commit->work);
259 else 260 else
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 3a44e705db53..97daf23f3fef 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -124,7 +124,7 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
124 unsigned long phys_addr = (unsigned long)dev_priv->stolen_base + 124 unsigned long phys_addr = (unsigned long)dev_priv->stolen_base +
125 psbfb->gtt->offset; 125 psbfb->gtt->offset;
126 126
127 page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 127 page_num = vma_pages(vma);
128 address = (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT); 128 address = (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT);
129 129
130 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 130 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
@@ -236,22 +236,20 @@ static int psb_framebuffer_init(struct drm_device *dev,
236 const struct drm_mode_fb_cmd2 *mode_cmd, 236 const struct drm_mode_fb_cmd2 *mode_cmd,
237 struct gtt_range *gt) 237 struct gtt_range *gt)
238{ 238{
239 u32 bpp, depth; 239 const struct drm_format_info *info;
240 int ret; 240 int ret;
241 241
242 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); 242 /*
243 * Reject unknown formats, YUV formats, and formats with more than
244 * 4 bytes per pixel.
245 */
246 info = drm_format_info(mode_cmd->pixel_format);
247 if (!info || !info->depth || info->cpp[0] > 4)
248 return -EINVAL;
243 249
244 if (mode_cmd->pitches[0] & 63) 250 if (mode_cmd->pitches[0] & 63)
245 return -EINVAL; 251 return -EINVAL;
246 switch (bpp) { 252
247 case 8:
248 case 16:
249 case 24:
250 case 32:
251 break;
252 default:
253 return -EINVAL;
254 }
255 drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd); 253 drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
256 fb->gtt = gt; 254 fb->gtt = gt;
257 ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs); 255 ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
@@ -298,7 +296,6 @@ static struct drm_framebuffer *psb_framebuffer_create
298 * psbfb_alloc - allocate frame buffer memory 296 * psbfb_alloc - allocate frame buffer memory
299 * @dev: the DRM device 297 * @dev: the DRM device
300 * @aligned_size: space needed 298 * @aligned_size: space needed
301 * @force: fall back to GEM buffers if need be
302 * 299 *
303 * Allocate the frame buffer. In the usual case we get a GTT range that 300 * Allocate the frame buffer. In the usual case we get a GTT range that
304 * is stolen memory backed and life is simple. If there isn't sufficient 301 * is stolen memory backed and life is simple. If there isn't sufficient
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 8f69225ce2b4..76aea2e7fb9d 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -76,6 +76,7 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
76 * psb_gtt_insert - put an object into the GTT 76 * psb_gtt_insert - put an object into the GTT
77 * @dev: our DRM device 77 * @dev: our DRM device
78 * @r: our GTT range 78 * @r: our GTT range
79 * @resume: on resume
79 * 80 *
80 * Take our preallocated GTT range and insert the GEM object into 81 * Take our preallocated GTT range and insert the GEM object into
81 * the GTT. This is protected via the gtt mutex which the caller 82 * the GTT. This is protected via the gtt mutex which the caller
@@ -321,6 +322,7 @@ out:
321 * @len: length (bytes) of address space required 322 * @len: length (bytes) of address space required
322 * @name: resource name 323 * @name: resource name
323 * @backed: resource should be backed by stolen pages 324 * @backed: resource should be backed by stolen pages
325 * @align: requested alignment
324 * 326 *
325 * Ask the kernel core to find us a suitable range of addresses 327 * Ask the kernel core to find us a suitable range of addresses
326 * to use for a GTT mapping. 328 * to use for a GTT mapping.
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 27b0e34dadec..6c7bb87f764e 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3941,10 +3941,9 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_i915_private *dev_priv,
3941 3941
3942 ret = drm_atomic_commit(state); 3942 ret = drm_atomic_commit(state);
3943out: 3943out:
3944 drm_modeset_unlock_all(dev);
3945 WARN(ret, "Toggling workaround to %i returns %i\n", enable, ret); 3944 WARN(ret, "Toggling workaround to %i returns %i\n", enable, ret);
3946 if (ret) 3945 drm_modeset_unlock_all(dev);
3947 drm_atomic_state_free(state); 3946 drm_atomic_state_put(state);
3948} 3947}
3949 3948
3950static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, 3949static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index b82de3072d4f..c762ae549a1c 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -142,8 +142,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
142 intel_state->clip.y2 = 142 intel_state->clip.y2 =
143 crtc_state->base.enable ? crtc_state->pipe_src_h : 0; 143 crtc_state->base.enable ? crtc_state->pipe_src_h : 0;
144 144
145 if (state->fb && intel_rotation_90_or_270(state->rotation)) { 145 if (state->fb && drm_rotation_90_or_270(state->rotation)) {
146 char *format_name; 146 char *format_name;
147
147 if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || 148 if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
148 state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) { 149 state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
149 DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n"); 150 DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fbcfed63a76e..4c21d2ec2c51 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2139,7 +2139,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
2139 const struct drm_framebuffer *fb, 2139 const struct drm_framebuffer *fb,
2140 unsigned int rotation) 2140 unsigned int rotation)
2141{ 2141{
2142 if (intel_rotation_90_or_270(rotation)) { 2142 if (drm_rotation_90_or_270(rotation)) {
2143 *view = i915_ggtt_view_rotated; 2143 *view = i915_ggtt_view_rotated;
2144 view->params.rotated = to_intel_framebuffer(fb)->rot_info; 2144 view->params.rotated = to_intel_framebuffer(fb)->rot_info;
2145 } else { 2145 } else {
@@ -2260,7 +2260,7 @@ void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
2260static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane, 2260static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane,
2261 unsigned int rotation) 2261 unsigned int rotation)
2262{ 2262{
2263 if (intel_rotation_90_or_270(rotation)) 2263 if (drm_rotation_90_or_270(rotation))
2264 return to_intel_framebuffer(fb)->rotated[plane].pitch; 2264 return to_intel_framebuffer(fb)->rotated[plane].pitch;
2265 else 2265 else
2266 return fb->pitches[plane]; 2266 return fb->pitches[plane];
@@ -2296,7 +2296,7 @@ void intel_add_fb_offsets(int *x, int *y,
2296 const struct intel_framebuffer *intel_fb = to_intel_framebuffer(state->base.fb); 2296 const struct intel_framebuffer *intel_fb = to_intel_framebuffer(state->base.fb);
2297 unsigned int rotation = state->base.rotation; 2297 unsigned int rotation = state->base.rotation;
2298 2298
2299 if (intel_rotation_90_or_270(rotation)) { 2299 if (drm_rotation_90_or_270(rotation)) {
2300 *x += intel_fb->rotated[plane].x; 2300 *x += intel_fb->rotated[plane].x;
2301 *y += intel_fb->rotated[plane].y; 2301 *y += intel_fb->rotated[plane].y;
2302 } else { 2302 } else {
@@ -2360,7 +2360,7 @@ static u32 intel_adjust_tile_offset(int *x, int *y,
2360 intel_tile_dims(dev_priv, &tile_width, &tile_height, 2360 intel_tile_dims(dev_priv, &tile_width, &tile_height,
2361 fb->modifier[plane], cpp); 2361 fb->modifier[plane], cpp);
2362 2362
2363 if (intel_rotation_90_or_270(rotation)) { 2363 if (drm_rotation_90_or_270(rotation)) {
2364 pitch_tiles = pitch / tile_height; 2364 pitch_tiles = pitch / tile_height;
2365 swap(tile_width, tile_height); 2365 swap(tile_width, tile_height);
2366 } else { 2366 } else {
@@ -2416,7 +2416,7 @@ static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv,
2416 intel_tile_dims(dev_priv, &tile_width, &tile_height, 2416 intel_tile_dims(dev_priv, &tile_width, &tile_height,
2417 fb_modifier, cpp); 2417 fb_modifier, cpp);
2418 2418
2419 if (intel_rotation_90_or_270(rotation)) { 2419 if (drm_rotation_90_or_270(rotation)) {
2420 pitch_tiles = pitch / tile_height; 2420 pitch_tiles = pitch / tile_height;
2421 swap(tile_width, tile_height); 2421 swap(tile_width, tile_height);
2422 } else { 2422 } else {
@@ -2976,7 +2976,7 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
2976 int ret; 2976 int ret;
2977 2977
2978 /* Rotate src coordinates to match rotated GTT view */ 2978 /* Rotate src coordinates to match rotated GTT view */
2979 if (intel_rotation_90_or_270(rotation)) 2979 if (drm_rotation_90_or_270(rotation))
2980 drm_rect_rotate(&plane_state->base.src, 2980 drm_rect_rotate(&plane_state->base.src,
2981 fb->width, fb->height, DRM_ROTATE_270); 2981 fb->width, fb->height, DRM_ROTATE_270);
2982 2982
@@ -3276,7 +3276,7 @@ u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
3276 * The stride is either expressed as a multiple of 64 bytes chunks for 3276 * The stride is either expressed as a multiple of 64 bytes chunks for
3277 * linear buffers or in number of tiles for tiled buffers. 3277 * linear buffers or in number of tiles for tiled buffers.
3278 */ 3278 */
3279 if (intel_rotation_90_or_270(rotation)) { 3279 if (drm_rotation_90_or_270(rotation)) {
3280 int cpp = drm_format_plane_cpp(fb->pixel_format, plane); 3280 int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
3281 3281
3282 stride /= intel_tile_height(dev_priv, fb->modifier[0], cpp); 3282 stride /= intel_tile_height(dev_priv, fb->modifier[0], cpp);
@@ -3584,7 +3584,7 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
3584 return; 3584 return;
3585 3585
3586err: 3586err:
3587 drm_atomic_state_free(state); 3587 drm_atomic_state_put(state);
3588} 3588}
3589 3589
3590void intel_finish_reset(struct drm_i915_private *dev_priv) 3590void intel_finish_reset(struct drm_i915_private *dev_priv)
@@ -3646,6 +3646,8 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
3646 intel_hpd_init(dev_priv); 3646 intel_hpd_init(dev_priv);
3647 } 3647 }
3648 3648
3649 if (state)
3650 drm_atomic_state_put(state);
3649 drm_modeset_drop_locks(ctx); 3651 drm_modeset_drop_locks(ctx);
3650 drm_modeset_acquire_fini(ctx); 3652 drm_modeset_acquire_fini(ctx);
3651 mutex_unlock(&dev->mode_config.mutex); 3653 mutex_unlock(&dev->mode_config.mutex);
@@ -4667,7 +4669,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
4667 to_intel_crtc(crtc_state->base.crtc); 4669 to_intel_crtc(crtc_state->base.crtc);
4668 int need_scaling; 4670 int need_scaling;
4669 4671
4670 need_scaling = intel_rotation_90_or_270(rotation) ? 4672 need_scaling = drm_rotation_90_or_270(rotation) ?
4671 (src_h != dst_w || src_w != dst_h): 4673 (src_h != dst_w || src_w != dst_h):
4672 (src_w != dst_w || src_h != dst_h); 4674 (src_w != dst_w || src_h != dst_h);
4673 4675
@@ -6885,7 +6887,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
6885 6887
6886 dev_priv->display.crtc_disable(crtc_state, state); 6888 dev_priv->display.crtc_disable(crtc_state, state);
6887 6889
6888 drm_atomic_state_free(state); 6890 drm_atomic_state_put(state);
6889 6891
6890 DRM_DEBUG_KMS("[CRTC:%d:%s] hw state adjusted, was enabled, now disabled\n", 6892 DRM_DEBUG_KMS("[CRTC:%d:%s] hw state adjusted, was enabled, now disabled\n",
6891 crtc->base.id, crtc->name); 6893 crtc->base.id, crtc->name);
@@ -11270,9 +11272,14 @@ found:
11270 return true; 11272 return true;
11271 11273
11272fail: 11274fail:
11273 drm_atomic_state_free(state); 11275 if (state) {
11274 drm_atomic_state_free(restore_state); 11276 drm_atomic_state_put(state);
11275 restore_state = state = NULL; 11277 state = NULL;
11278 }
11279 if (restore_state) {
11280 drm_atomic_state_put(restore_state);
11281 restore_state = NULL;
11282 }
11276 11283
11277 if (ret == -EDEADLK) { 11284 if (ret == -EDEADLK) {
11278 drm_modeset_backoff(ctx); 11285 drm_modeset_backoff(ctx);
@@ -11300,10 +11307,9 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
11300 return; 11307 return;
11301 11308
11302 ret = drm_atomic_commit(state); 11309 ret = drm_atomic_commit(state);
11303 if (ret) { 11310 if (ret)
11304 DRM_DEBUG_KMS("Couldn't release load detect pipe: %i\n", ret); 11311 DRM_DEBUG_KMS("Couldn't release load detect pipe: %i\n", ret);
11305 drm_atomic_state_free(state); 11312 drm_atomic_state_put(state);
11306 }
11307} 11313}
11308 11314
11309static int i9xx_pll_refclk(struct drm_device *dev, 11315static int i9xx_pll_refclk(struct drm_device *dev,
@@ -12371,8 +12377,7 @@ retry:
12371 goto retry; 12377 goto retry;
12372 } 12378 }
12373 12379
12374 if (ret) 12380 drm_atomic_state_put(state);
12375 drm_atomic_state_free(state);
12376 12381
12377 if (ret == 0 && event) { 12382 if (ret == 0 && event) {
12378 spin_lock_irq(&dev->event_lock); 12383 spin_lock_irq(&dev->event_lock);
@@ -14457,7 +14462,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
14457 14462
14458 drm_atomic_helper_commit_cleanup_done(state); 14463 drm_atomic_helper_commit_cleanup_done(state);
14459 14464
14460 drm_atomic_state_free(state); 14465 drm_atomic_state_put(state);
14461 14466
14462 /* As one of the primary mmio accessors, KMS has a high likelihood 14467 /* As one of the primary mmio accessors, KMS has a high likelihood
14463 * of triggering bugs in unclaimed access. After we finish 14468 * of triggering bugs in unclaimed access. After we finish
@@ -14540,6 +14545,7 @@ static int intel_atomic_commit(struct drm_device *dev,
14540 intel_shared_dpll_commit(state); 14545 intel_shared_dpll_commit(state);
14541 intel_atomic_track_fbs(state); 14546 intel_atomic_track_fbs(state);
14542 14547
14548 drm_atomic_state_get(state);
14543 if (nonblock) 14549 if (nonblock)
14544 queue_work(system_unbound_wq, &state->commit_work); 14550 queue_work(system_unbound_wq, &state->commit_work);
14545 else 14551 else
@@ -14581,9 +14587,8 @@ retry:
14581 goto retry; 14587 goto retry;
14582 } 14588 }
14583 14589
14584 if (ret)
14585out: 14590out:
14586 drm_atomic_state_free(state); 14591 drm_atomic_state_put(state);
14587} 14592}
14588 14593
14589/* 14594/*
@@ -14901,6 +14906,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
14901 struct intel_plane *primary = NULL; 14906 struct intel_plane *primary = NULL;
14902 struct intel_plane_state *state = NULL; 14907 struct intel_plane_state *state = NULL;
14903 const uint32_t *intel_primary_formats; 14908 const uint32_t *intel_primary_formats;
14909 unsigned int supported_rotations;
14904 unsigned int num_formats; 14910 unsigned int num_formats;
14905 int ret; 14911 int ret;
14906 14912
@@ -14973,8 +14979,21 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
14973 if (ret) 14979 if (ret)
14974 goto fail; 14980 goto fail;
14975 14981
14976 if (INTEL_INFO(dev)->gen >= 4) 14982 if (INTEL_GEN(dev) >= 9) {
14977 intel_create_rotation_property(dev, primary); 14983 supported_rotations =
14984 DRM_ROTATE_0 | DRM_ROTATE_90 |
14985 DRM_ROTATE_180 | DRM_ROTATE_270;
14986 } else if (INTEL_GEN(dev) >= 4) {
14987 supported_rotations =
14988 DRM_ROTATE_0 | DRM_ROTATE_180;
14989 } else {
14990 supported_rotations = DRM_ROTATE_0;
14991 }
14992
14993 if (INTEL_GEN(dev) >= 4)
14994 drm_plane_create_rotation_property(&primary->base,
14995 DRM_ROTATE_0,
14996 supported_rotations);
14978 14997
14979 drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); 14998 drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
14980 14999
@@ -14987,24 +15006,6 @@ fail:
14987 return NULL; 15006 return NULL;
14988} 15007}
14989 15008
14990void intel_create_rotation_property(struct drm_device *dev, struct intel_plane *plane)
14991{
14992 if (!dev->mode_config.rotation_property) {
14993 unsigned long flags = DRM_ROTATE_0 |
14994 DRM_ROTATE_180;
14995
14996 if (INTEL_INFO(dev)->gen >= 9)
14997 flags |= DRM_ROTATE_90 | DRM_ROTATE_270;
14998
14999 dev->mode_config.rotation_property =
15000 drm_mode_create_rotation_property(dev, flags);
15001 }
15002 if (dev->mode_config.rotation_property)
15003 drm_object_attach_property(&plane->base.base,
15004 dev->mode_config.rotation_property,
15005 plane->base.state->rotation);
15006}
15007
15008static int 15009static int
15009intel_check_cursor_plane(struct drm_plane *plane, 15010intel_check_cursor_plane(struct drm_plane *plane,
15010 struct intel_crtc_state *crtc_state, 15011 struct intel_crtc_state *crtc_state,
@@ -15131,17 +15132,11 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
15131 if (ret) 15132 if (ret)
15132 goto fail; 15133 goto fail;
15133 15134
15134 if (INTEL_INFO(dev)->gen >= 4) { 15135 if (INTEL_GEN(dev) >= 4)
15135 if (!dev->mode_config.rotation_property) 15136 drm_plane_create_rotation_property(&cursor->base,
15136 dev->mode_config.rotation_property = 15137 DRM_ROTATE_0,
15137 drm_mode_create_rotation_property(dev, 15138 DRM_ROTATE_0 |
15138 DRM_ROTATE_0 | 15139 DRM_ROTATE_180);
15139 DRM_ROTATE_180);
15140 if (dev->mode_config.rotation_property)
15141 drm_object_attach_property(&cursor->base.base,
15142 dev->mode_config.rotation_property,
15143 state->base.rotation);
15144 }
15145 15140
15146 if (INTEL_INFO(dev)->gen >=9) 15141 if (INTEL_INFO(dev)->gen >=9)
15147 state->scaler_id = -1; 15142 state->scaler_id = -1;
@@ -16314,7 +16309,7 @@ retry:
16314 * BIOS-programmed watermarks untouched and hope for the best. 16309 * BIOS-programmed watermarks untouched and hope for the best.
16315 */ 16310 */
16316 WARN(true, "Could not determine valid watermarks for inherited state\n"); 16311 WARN(true, "Could not determine valid watermarks for inherited state\n");
16317 goto fail; 16312 goto put_state;
16318 } 16313 }
16319 16314
16320 /* Write calculated watermark values back */ 16315 /* Write calculated watermark values back */
@@ -16325,7 +16320,8 @@ retry:
16325 dev_priv->display.optimize_watermarks(cs); 16320 dev_priv->display.optimize_watermarks(cs);
16326 } 16321 }
16327 16322
16328 drm_atomic_state_free(state); 16323put_state:
16324 drm_atomic_state_put(state);
16329fail: 16325fail:
16330 drm_modeset_drop_locks(&ctx); 16326 drm_modeset_drop_locks(&ctx);
16331 drm_modeset_acquire_fini(&ctx); 16327 drm_modeset_acquire_fini(&ctx);
@@ -16963,10 +16959,9 @@ void intel_display_resume(struct drm_device *dev)
16963 drm_modeset_acquire_fini(&ctx); 16959 drm_modeset_acquire_fini(&ctx);
16964 mutex_unlock(&dev->mode_config.mutex); 16960 mutex_unlock(&dev->mode_config.mutex);
16965 16961
16966 if (ret) { 16962 if (ret)
16967 DRM_ERROR("Restoring old state failed with %i\n", ret); 16963 DRM_ERROR("Restoring old state failed with %i\n", ret);
16968 drm_atomic_state_free(state); 16964 drm_atomic_state_put(state);
16969 }
16970} 16965}
16971 16966
16972void intel_modeset_gem_init(struct drm_device *dev) 16967void intel_modeset_gem_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a19ec06f9e42..3ffba2def09c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1285,15 +1285,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
1285unsigned int intel_tile_height(const struct drm_i915_private *dev_priv, 1285unsigned int intel_tile_height(const struct drm_i915_private *dev_priv,
1286 uint64_t fb_modifier, unsigned int cpp); 1286 uint64_t fb_modifier, unsigned int cpp);
1287 1287
1288static inline bool
1289intel_rotation_90_or_270(unsigned int rotation)
1290{
1291 return rotation & (DRM_ROTATE_90 | DRM_ROTATE_270);
1292}
1293
1294void intel_create_rotation_property(struct drm_device *dev,
1295 struct intel_plane *plane);
1296
1297void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, 1288void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
1298 enum pipe pipe); 1289 enum pipe pipe);
1299 1290
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index faa67624e1ed..afc040be1172 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -84,7 +84,7 @@ static void intel_fbc_get_plane_source_size(struct intel_fbc_state_cache *cache,
84{ 84{
85 int w, h; 85 int w, h;
86 86
87 if (intel_rotation_90_or_270(cache->plane.rotation)) { 87 if (drm_rotation_90_or_270(cache->plane.rotation)) {
88 w = cache->plane.src_h; 88 w = cache->plane.src_h;
89 h = cache->plane.src_w; 89 h = cache->plane.src_w;
90 } else { 90 } else {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a2f751cd187a..e2f0a32279e7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3173,7 +3173,7 @@ skl_plane_downscale_amount(const struct intel_plane_state *pstate)
3173 src_h = drm_rect_height(&pstate->base.src); 3173 src_h = drm_rect_height(&pstate->base.src);
3174 dst_w = drm_rect_width(&pstate->base.dst); 3174 dst_w = drm_rect_width(&pstate->base.dst);
3175 dst_h = drm_rect_height(&pstate->base.dst); 3175 dst_h = drm_rect_height(&pstate->base.dst);
3176 if (intel_rotation_90_or_270(pstate->base.rotation)) 3176 if (drm_rotation_90_or_270(pstate->base.rotation))
3177 swap(dst_w, dst_h); 3177 swap(dst_w, dst_h);
3178 3178
3179 downscale_h = max(src_h / dst_h, (uint32_t)DRM_PLANE_HELPER_NO_SCALING); 3179 downscale_h = max(src_h / dst_h, (uint32_t)DRM_PLANE_HELPER_NO_SCALING);
@@ -3204,7 +3204,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
3204 width = drm_rect_width(&intel_pstate->base.src) >> 16; 3204 width = drm_rect_width(&intel_pstate->base.src) >> 16;
3205 height = drm_rect_height(&intel_pstate->base.src) >> 16; 3205 height = drm_rect_height(&intel_pstate->base.src) >> 16;
3206 3206
3207 if (intel_rotation_90_or_270(pstate->rotation)) 3207 if (drm_rotation_90_or_270(pstate->rotation))
3208 swap(width, height); 3208 swap(width, height);
3209 3209
3210 /* for planar format */ 3210 /* for planar format */
@@ -3304,7 +3304,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
3304 src_w = drm_rect_width(&intel_pstate->base.src) >> 16; 3304 src_w = drm_rect_width(&intel_pstate->base.src) >> 16;
3305 src_h = drm_rect_height(&intel_pstate->base.src) >> 16; 3305 src_h = drm_rect_height(&intel_pstate->base.src) >> 16;
3306 3306
3307 if (intel_rotation_90_or_270(pstate->rotation)) 3307 if (drm_rotation_90_or_270(pstate->rotation))
3308 swap(src_w, src_h); 3308 swap(src_w, src_h);
3309 3309
3310 /* Halve UV plane width and height for NV12 */ 3310 /* Halve UV plane width and height for NV12 */
@@ -3318,7 +3318,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
3318 else 3318 else
3319 plane_bpp = drm_format_plane_cpp(fb->pixel_format, 0); 3319 plane_bpp = drm_format_plane_cpp(fb->pixel_format, 0);
3320 3320
3321 if (intel_rotation_90_or_270(pstate->rotation)) { 3321 if (drm_rotation_90_or_270(pstate->rotation)) {
3322 switch (plane_bpp) { 3322 switch (plane_bpp) {
3323 case 1: 3323 case 1:
3324 min_scanlines = 32; 3324 min_scanlines = 32;
@@ -3562,13 +3562,13 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
3562 width = drm_rect_width(&intel_pstate->base.src) >> 16; 3562 width = drm_rect_width(&intel_pstate->base.src) >> 16;
3563 height = drm_rect_height(&intel_pstate->base.src) >> 16; 3563 height = drm_rect_height(&intel_pstate->base.src) >> 16;
3564 3564
3565 if (intel_rotation_90_or_270(pstate->rotation)) 3565 if (drm_rotation_90_or_270(pstate->rotation))
3566 swap(width, height); 3566 swap(width, height);
3567 3567
3568 cpp = drm_format_plane_cpp(fb->pixel_format, 0); 3568 cpp = drm_format_plane_cpp(fb->pixel_format, 0);
3569 plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate); 3569 plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate);
3570 3570
3571 if (intel_rotation_90_or_270(pstate->rotation)) { 3571 if (drm_rotation_90_or_270(pstate->rotation)) {
3572 int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ? 3572 int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
3573 drm_format_plane_cpp(fb->pixel_format, 1) : 3573 drm_format_plane_cpp(fb->pixel_format, 1) :
3574 drm_format_plane_cpp(fb->pixel_format, 0); 3574 drm_format_plane_cpp(fb->pixel_format, 0);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 73a521fdf1bd..3ea6419e18b9 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -987,9 +987,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
987 drm_modeset_backoff(&ctx); 987 drm_modeset_backoff(&ctx);
988 } 988 }
989 989
990 if (ret) 990 drm_atomic_state_put(state);
991 drm_atomic_state_free(state);
992
993out: 991out:
994 drm_modeset_drop_locks(&ctx); 992 drm_modeset_drop_locks(&ctx);
995 drm_modeset_acquire_fini(&ctx); 993 drm_modeset_acquire_fini(&ctx);
@@ -1046,6 +1044,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1046 struct intel_plane_state *state = NULL; 1044 struct intel_plane_state *state = NULL;
1047 unsigned long possible_crtcs; 1045 unsigned long possible_crtcs;
1048 const uint32_t *plane_formats; 1046 const uint32_t *plane_formats;
1047 unsigned int supported_rotations;
1049 int num_plane_formats; 1048 int num_plane_formats;
1050 int ret; 1049 int ret;
1051 1050
@@ -1121,6 +1120,15 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1121 goto fail; 1120 goto fail;
1122 } 1121 }
1123 1122
1123 if (INTEL_GEN(dev) >= 9) {
1124 supported_rotations =
1125 DRM_ROTATE_0 | DRM_ROTATE_90 |
1126 DRM_ROTATE_180 | DRM_ROTATE_270;
1127 } else {
1128 supported_rotations =
1129 DRM_ROTATE_0 | DRM_ROTATE_180;
1130 }
1131
1124 intel_plane->pipe = pipe; 1132 intel_plane->pipe = pipe;
1125 intel_plane->plane = plane; 1133 intel_plane->plane = plane;
1126 intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane); 1134 intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane);
@@ -1143,7 +1151,9 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1143 if (ret) 1151 if (ret)
1144 goto fail; 1152 goto fail;
1145 1153
1146 intel_create_rotation_property(dev, intel_plane); 1154 drm_plane_create_rotation_property(&intel_plane->base,
1155 DRM_ROTATE_0,
1156 supported_rotations);
1147 1157
1148 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); 1158 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
1149 1159
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index cf83f6507ec8..db61aa5f32ef 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -83,7 +83,7 @@ static void mtk_atomic_complete(struct mtk_drm_private *private,
83 drm_atomic_helper_wait_for_vblanks(drm, state); 83 drm_atomic_helper_wait_for_vblanks(drm, state);
84 84
85 drm_atomic_helper_cleanup_planes(drm, state); 85 drm_atomic_helper_cleanup_planes(drm, state);
86 drm_atomic_state_free(state); 86 drm_atomic_state_put(state);
87} 87}
88 88
89static void mtk_atomic_work(struct work_struct *work) 89static void mtk_atomic_work(struct work_struct *work)
@@ -110,6 +110,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
110 110
111 drm_atomic_helper_swap_state(state, true); 111 drm_atomic_helper_swap_state(state, true);
112 112
113 drm_atomic_state_get(state);
113 if (async) 114 if (async)
114 mtk_atomic_schedule(private, state); 115 mtk_atomic_schedule(private, state);
115 else 116 else
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 73bae382eac3..db193f835298 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -141,7 +141,7 @@ static void complete_commit(struct msm_commit *c, bool async)
141 141
142 kms->funcs->complete_commit(kms, state); 142 kms->funcs->complete_commit(kms, state);
143 143
144 drm_atomic_state_free(state); 144 drm_atomic_state_put(state);
145 145
146 commit_destroy(c); 146 commit_destroy(c);
147} 147}
@@ -256,6 +256,7 @@ int msm_atomic_commit(struct drm_device *dev,
256 * current layout. 256 * current layout.
257 */ 257 */
258 258
259 drm_atomic_state_get(state);
259 if (nonblock) { 260 if (nonblock) {
260 queue_work(priv->atomic_wq, &c->work); 261 queue_work(priv->atomic_wq, &c->work);
261 return 0; 262 return 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 72e2399bce39..0bd7164bc817 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -861,6 +861,7 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
861 struct nouveau_bo *nvbo; 861 struct nouveau_bo *nvbo;
862 bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT); 862 bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
863 bool write = !!(req->flags & NOUVEAU_GEM_CPU_PREP_WRITE); 863 bool write = !!(req->flags & NOUVEAU_GEM_CPU_PREP_WRITE);
864 long lret;
864 int ret; 865 int ret;
865 866
866 gem = drm_gem_object_lookup(file_priv, req->handle); 867 gem = drm_gem_object_lookup(file_priv, req->handle);
@@ -868,19 +869,15 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
868 return -ENOENT; 869 return -ENOENT;
869 nvbo = nouveau_gem_object(gem); 870 nvbo = nouveau_gem_object(gem);
870 871
871 if (no_wait) 872 lret = reservation_object_wait_timeout_rcu(nvbo->bo.resv, write, true,
872 ret = reservation_object_test_signaled_rcu(nvbo->bo.resv, write) ? 0 : -EBUSY; 873 no_wait ? 0 : 30 * HZ);
873 else { 874 if (!lret)
874 long lret; 875 ret = -EBUSY;
876 else if (lret > 0)
877 ret = 0;
878 else
879 ret = lret;
875 880
876 lret = reservation_object_wait_timeout_rcu(nvbo->bo.resv, write, true, 30 * HZ);
877 if (!lret)
878 ret = -EBUSY;
879 else if (lret > 0)
880 ret = 0;
881 else
882 ret = lret;
883 }
884 nouveau_bo_sync_for_cpu(nvbo); 881 nouveau_bo_sync_for_cpu(nvbo);
885 drm_gem_object_unreference_unlocked(gem); 882 drm_gem_object_unreference_unlocked(gem);
886 883
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 180f644e861e..16c691dbc372 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -438,13 +438,14 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
438 } 438 }
439} 439}
440 440
441static bool omap_crtc_is_plane_prop(struct drm_device *dev, 441static bool omap_crtc_is_plane_prop(struct drm_crtc *crtc,
442 struct drm_property *property) 442 struct drm_property *property)
443{ 443{
444 struct drm_device *dev = crtc->dev;
444 struct omap_drm_private *priv = dev->dev_private; 445 struct omap_drm_private *priv = dev->dev_private;
445 446
446 return property == priv->zorder_prop || 447 return property == priv->zorder_prop ||
447 property == dev->mode_config.rotation_property; 448 property == crtc->primary->rotation_property;
448} 449}
449 450
450static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, 451static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
@@ -452,9 +453,7 @@ static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
452 struct drm_property *property, 453 struct drm_property *property,
453 uint64_t val) 454 uint64_t val)
454{ 455{
455 struct drm_device *dev = crtc->dev; 456 if (omap_crtc_is_plane_prop(crtc, property)) {
456
457 if (omap_crtc_is_plane_prop(dev, property)) {
458 struct drm_plane_state *plane_state; 457 struct drm_plane_state *plane_state;
459 struct drm_plane *plane = crtc->primary; 458 struct drm_plane *plane = crtc->primary;
460 459
@@ -479,9 +478,7 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
479 struct drm_property *property, 478 struct drm_property *property,
480 uint64_t *val) 479 uint64_t *val)
481{ 480{
482 struct drm_device *dev = crtc->dev; 481 if (omap_crtc_is_plane_prop(crtc, property)) {
483
484 if (omap_crtc_is_plane_prop(dev, property)) {
485 /* 482 /*
486 * Delegate property get to the primary plane. The 483 * Delegate property get to the primary plane. The
487 * drm_atomic_plane_get_property() function isn't exported, but 484 * drm_atomic_plane_get_property() function isn't exported, but
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index e1cfba51cff6..39c5312b466c 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -105,7 +105,7 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
105 105
106 dispc_runtime_put(); 106 dispc_runtime_put();
107 107
108 drm_atomic_state_free(old_state); 108 drm_atomic_state_put(old_state);
109 109
110 /* Complete the commit, wake up any waiter. */ 110 /* Complete the commit, wake up any waiter. */
111 spin_lock(&priv->commit.lock); 111 spin_lock(&priv->commit.lock);
@@ -176,6 +176,7 @@ static int omap_atomic_commit(struct drm_device *dev,
176 /* Swap the state, this is the point of no return. */ 176 /* Swap the state, this is the point of no return. */
177 drm_atomic_helper_swap_state(state, true); 177 drm_atomic_helper_swap_state(state, true);
178 178
179 drm_atomic_state_get(state);
179 if (nonblock) 180 if (nonblock)
180 schedule_work(&commit->work); 181 schedule_work(&commit->work);
181 else 182 else
@@ -292,16 +293,6 @@ static int omap_modeset_init_properties(struct drm_device *dev)
292{ 293{
293 struct omap_drm_private *priv = dev->dev_private; 294 struct omap_drm_private *priv = dev->dev_private;
294 295
295 if (priv->has_dmm) {
296 dev->mode_config.rotation_property =
297 drm_mode_create_rotation_property(dev,
298 DRM_ROTATE_0 | DRM_ROTATE_90 |
299 DRM_ROTATE_180 | DRM_ROTATE_270 |
300 DRM_REFLECT_X | DRM_REFLECT_Y);
301 if (!dev->mode_config.rotation_property)
302 return -ENOMEM;
303 }
304
305 priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0, 3); 296 priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0, 3);
306 if (!priv->zorder_prop) 297 if (!priv->zorder_prop)
307 return -ENOMEM; 298 return -ENOMEM;
@@ -752,22 +743,32 @@ static void dev_lastclose(struct drm_device *dev)
752 743
753 DBG("lastclose: dev=%p", dev); 744 DBG("lastclose: dev=%p", dev);
754 745
755 if (dev->mode_config.rotation_property) { 746 /* need to restore default rotation state.. not sure
756 /* need to restore default rotation state.. not sure 747 * if there is a cleaner way to restore properties to
757 * if there is a cleaner way to restore properties to 748 * default state? Maybe a flag that properties should
758 * default state? Maybe a flag that properties should 749 * automatically be restored to default state on
759 * automatically be restored to default state on 750 * lastclose?
760 * lastclose? 751 */
761 */ 752 for (i = 0; i < priv->num_crtcs; i++) {
762 for (i = 0; i < priv->num_crtcs; i++) { 753 struct drm_crtc *crtc = priv->crtcs[i];
763 drm_object_property_set_value(&priv->crtcs[i]->base,
764 dev->mode_config.rotation_property, 0);
765 }
766 754
767 for (i = 0; i < priv->num_planes; i++) { 755 if (!crtc->primary->rotation_property)
768 drm_object_property_set_value(&priv->planes[i]->base, 756 continue;
769 dev->mode_config.rotation_property, 0); 757
770 } 758 drm_object_property_set_value(&crtc->base,
759 crtc->primary->rotation_property,
760 DRM_ROTATE_0);
761 }
762
763 for (i = 0; i < priv->num_planes; i++) {
764 struct drm_plane *plane = priv->planes[i];
765
766 if (!plane->rotation_property)
767 continue;
768
769 drm_object_property_set_value(&plane->base,
770 plane->rotation_property,
771 DRM_ROTATE_0);
771 } 772 }
772 773
773 if (priv->fbdev) { 774 if (priv->fbdev) {
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 66ac8c40db26..0ffd5b930ec0 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -108,16 +108,12 @@ static void omap_plane_atomic_update(struct drm_plane *plane,
108 win.src_x = state->src_x >> 16; 108 win.src_x = state->src_x >> 16;
109 win.src_y = state->src_y >> 16; 109 win.src_y = state->src_y >> 16;
110 110
111 switch (state->rotation & DRM_ROTATE_MASK) { 111 if (drm_rotation_90_or_270(state->rotation)) {
112 case DRM_ROTATE_90:
113 case DRM_ROTATE_270:
114 win.src_w = state->src_h >> 16; 112 win.src_w = state->src_h >> 16;
115 win.src_h = state->src_w >> 16; 113 win.src_h = state->src_w >> 16;
116 break; 114 } else {
117 default:
118 win.src_w = state->src_w >> 16; 115 win.src_w = state->src_w >> 16;
119 win.src_h = state->src_h >> 16; 116 win.src_h = state->src_h >> 16;
120 break;
121 } 117 }
122 118
123 /* update scanout: */ 119 /* update scanout: */
@@ -215,9 +211,17 @@ void omap_plane_install_properties(struct drm_plane *plane,
215 struct omap_drm_private *priv = dev->dev_private; 211 struct omap_drm_private *priv = dev->dev_private;
216 212
217 if (priv->has_dmm) { 213 if (priv->has_dmm) {
218 struct drm_property *prop = dev->mode_config.rotation_property; 214 if (!plane->rotation_property)
219 215 drm_plane_create_rotation_property(plane,
220 drm_object_attach_property(obj, prop, 0); 216 DRM_ROTATE_0,
217 DRM_ROTATE_0 | DRM_ROTATE_90 |
218 DRM_ROTATE_180 | DRM_ROTATE_270 |
219 DRM_REFLECT_X | DRM_REFLECT_Y);
220
221 /* Attach the rotation property also to the crtc object */
222 if (plane->rotation_property && obj != &plane->base)
223 drm_object_attach_property(obj, plane->rotation_property,
224 DRM_ROTATE_0);
221 } 225 }
222 226
223 drm_object_attach_property(obj, priv->zorder_prop, 0); 227 drm_object_attach_property(obj, priv->zorder_prop, 0);
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 0daad446d2c7..f65f29911dca 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -89,13 +89,13 @@ static struct fb_ops radeonfb_ops = {
89}; 89};
90 90
91 91
92int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) 92int radeon_align_pitch(struct radeon_device *rdev, int width, int cpp, bool tiled)
93{ 93{
94 int aligned = width; 94 int aligned = width;
95 int align_large = (ASIC_IS_AVIVO(rdev)) || tiled; 95 int align_large = (ASIC_IS_AVIVO(rdev)) || tiled;
96 int pitch_mask = 0; 96 int pitch_mask = 0;
97 97
98 switch (bpp / 8) { 98 switch (cpp) {
99 case 1: 99 case 1:
100 pitch_mask = align_large ? 255 : 127; 100 pitch_mask = align_large ? 255 : 127;
101 break; 101 break;
@@ -110,7 +110,7 @@ int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tile
110 110
111 aligned += pitch_mask; 111 aligned += pitch_mask;
112 aligned &= ~pitch_mask; 112 aligned &= ~pitch_mask;
113 return aligned; 113 return aligned * cpp;
114} 114}
115 115
116static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) 116static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
@@ -139,13 +139,13 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
139 int ret; 139 int ret;
140 int aligned_size, size; 140 int aligned_size, size;
141 int height = mode_cmd->height; 141 int height = mode_cmd->height;
142 u32 bpp, depth; 142 u32 cpp;
143 143
144 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); 144 cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
145 145
146 /* need to align pitch with crtc limits */ 146 /* need to align pitch with crtc limits */
147 mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, bpp, 147 mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, cpp,
148 fb_tiled) * ((bpp + 1) / 8); 148 fb_tiled);
149 149
150 if (rdev->family >= CHIP_R600) 150 if (rdev->family >= CHIP_R600)
151 height = ALIGN(mode_cmd->height, 8); 151 height = ALIGN(mode_cmd->height, 8);
@@ -165,11 +165,11 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
165 tiling_flags = RADEON_TILING_MACRO; 165 tiling_flags = RADEON_TILING_MACRO;
166 166
167#ifdef __BIG_ENDIAN 167#ifdef __BIG_ENDIAN
168 switch (bpp) { 168 switch (cpp) {
169 case 32: 169 case 4:
170 tiling_flags |= RADEON_TILING_SWAP_32BIT; 170 tiling_flags |= RADEON_TILING_SWAP_32BIT;
171 break; 171 break;
172 case 16: 172 case 2:
173 tiling_flags |= RADEON_TILING_SWAP_16BIT; 173 tiling_flags |= RADEON_TILING_SWAP_16BIT;
174 default: 174 default:
175 break; 175 break;
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index deb9511725c9..0bcffd8a7bd3 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -745,7 +745,8 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
745 uint32_t handle; 745 uint32_t handle;
746 int r; 746 int r;
747 747
748 args->pitch = radeon_align_pitch(rdev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8); 748 args->pitch = radeon_align_pitch(rdev, args->width,
749 DIV_ROUND_UP(args->bpp, 8), 0);
749 args->size = args->pitch * args->height; 750 args->size = args->pitch * args->height;
750 args->size = ALIGN(args->size, PAGE_SIZE); 751 args->size = ALIGN(args->size, PAGE_SIZE);
751 752
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index bd9c3bb9252c..c76ed9ee6a01 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -264,7 +264,7 @@ static void rcar_du_atomic_complete(struct rcar_du_commit *commit)
264 264
265 drm_atomic_helper_cleanup_planes(dev, old_state); 265 drm_atomic_helper_cleanup_planes(dev, old_state);
266 266
267 drm_atomic_state_free(old_state); 267 drm_atomic_state_put(old_state);
268 268
269 /* Complete the commit, wake up any waiter. */ 269 /* Complete the commit, wake up any waiter. */
270 spin_lock(&rcdu->commit.wait.lock); 270 spin_lock(&rcdu->commit.wait.lock);
@@ -330,6 +330,7 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
330 /* Swap the state, this is the point of no return. */ 330 /* Swap the state, this is the point of no return. */
331 drm_atomic_helper_swap_state(state, true); 331 drm_atomic_helper_swap_state(state, true);
332 332
333 drm_atomic_state_get(state);
333 if (nonblock) 334 if (nonblock)
334 schedule_work(&commit->work); 335 schedule_work(&commit->work);
335 else 336 else
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 3c58669a06ce..6f7f9c59f05b 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -1,7 +1,6 @@
1config DRM_ROCKCHIP 1config DRM_ROCKCHIP
2 tristate "DRM Support for Rockchip" 2 tristate "DRM Support for Rockchip"
3 depends on DRM && ROCKCHIP_IOMMU 3 depends on DRM && ROCKCHIP_IOMMU
4 depends on RESET_CONTROLLER
5 select DRM_GEM_CMA_HELPER 4 select DRM_GEM_CMA_HELPER
6 select DRM_KMS_HELPER 5 select DRM_KMS_HELPER
7 select DRM_PANEL 6 select DRM_PANEL
diff --git a/drivers/gpu/drm/savage/savage_state.c b/drivers/gpu/drm/savage/savage_state.c
index 3dc0d8ff95ec..2db89bed52e8 100644
--- a/drivers/gpu/drm/savage/savage_state.c
+++ b/drivers/gpu/drm/savage/savage_state.c
@@ -1004,6 +1004,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
1004 kvb_addr = memdup_user(cmdbuf->vb_addr, cmdbuf->vb_size); 1004 kvb_addr = memdup_user(cmdbuf->vb_addr, cmdbuf->vb_size);
1005 if (IS_ERR(kvb_addr)) { 1005 if (IS_ERR(kvb_addr)) {
1006 ret = PTR_ERR(kvb_addr); 1006 ret = PTR_ERR(kvb_addr);
1007 kvb_addr = NULL;
1007 goto done; 1008 goto done;
1008 } 1009 }
1009 cmdbuf->vb_addr = kvb_addr; 1010 cmdbuf->vb_addr = kvb_addr;
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index 2784919a7366..7087499969bc 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -184,7 +184,7 @@ static void sti_atomic_complete(struct sti_private *private,
184 drm_atomic_helper_wait_for_vblanks(drm, state); 184 drm_atomic_helper_wait_for_vblanks(drm, state);
185 185
186 drm_atomic_helper_cleanup_planes(drm, state); 186 drm_atomic_helper_cleanup_planes(drm, state);
187 drm_atomic_state_free(state); 187 drm_atomic_state_put(state);
188} 188}
189 189
190static void sti_atomic_work(struct work_struct *work) 190static void sti_atomic_work(struct work_struct *work)
@@ -217,6 +217,7 @@ static int sti_atomic_commit(struct drm_device *drm,
217 217
218 drm_atomic_helper_swap_state(state, true); 218 drm_atomic_helper_swap_state(state, true);
219 219
220 drm_atomic_state_get(state);
220 if (nonblock) 221 if (nonblock)
221 sti_atomic_schedule(private, state); 222 sti_atomic_schedule(private, state);
222 else 223 else
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 63ebb154b9b5..bbf5a4b7e0b6 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -3,7 +3,6 @@ config DRM_TEGRA
3 depends on ARCH_TEGRA || (ARM && COMPILE_TEST) 3 depends on ARCH_TEGRA || (ARM && COMPILE_TEST)
4 depends on COMMON_CLK 4 depends on COMMON_CLK
5 depends on DRM 5 depends on DRM
6 depends on RESET_CONTROLLER
7 select DRM_KMS_HELPER 6 select DRM_KMS_HELPER
8 select DRM_MIPI_DSI 7 select DRM_MIPI_DSI
9 select DRM_PANEL 8 select DRM_PANEL
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 8ab47b502d83..a9630c2d6cb3 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -63,7 +63,7 @@ static void tegra_atomic_complete(struct tegra_drm *tegra,
63 drm_atomic_helper_wait_for_vblanks(drm, state); 63 drm_atomic_helper_wait_for_vblanks(drm, state);
64 64
65 drm_atomic_helper_cleanup_planes(drm, state); 65 drm_atomic_helper_cleanup_planes(drm, state);
66 drm_atomic_state_free(state); 66 drm_atomic_state_put(state);
67} 67}
68 68
69static void tegra_atomic_work(struct work_struct *work) 69static void tegra_atomic_work(struct work_struct *work)
@@ -96,6 +96,7 @@ static int tegra_atomic_commit(struct drm_device *drm,
96 96
97 drm_atomic_helper_swap_state(state, true); 97 drm_atomic_helper_swap_state(state, true);
98 98
99 drm_atomic_state_get(state);
99 if (nonblock) 100 if (nonblock)
100 tegra_atomic_schedule(tegra, state); 101 tegra_atomic_schedule(tegra, state);
101 else 102 else
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 52ebe8fc1784..822531ebd4b0 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -72,16 +72,14 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
72 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 72 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
73 struct drm_device *dev = crtc->dev; 73 struct drm_device *dev = crtc->dev;
74 struct drm_gem_cma_object *gem; 74 struct drm_gem_cma_object *gem;
75 unsigned int depth, bpp;
76 dma_addr_t start, end; 75 dma_addr_t start, end;
77 u64 dma_base_and_ceiling; 76 u64 dma_base_and_ceiling;
78 77
79 drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
80 gem = drm_fb_cma_get_gem_obj(fb, 0); 78 gem = drm_fb_cma_get_gem_obj(fb, 0);
81 79
82 start = gem->paddr + fb->offsets[0] + 80 start = gem->paddr + fb->offsets[0] +
83 crtc->y * fb->pitches[0] + 81 crtc->y * fb->pitches[0] +
84 crtc->x * bpp / 8; 82 crtc->x * drm_format_plane_cpp(fb->pixel_format, 0);
85 83
86 end = start + (crtc->mode.vdisplay * fb->pitches[0]); 84 end = start + (crtc->mode.vdisplay * fb->pitches[0]);
87 85
@@ -461,16 +459,16 @@ static void tilcdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
461 if (info->tft_alt_mode) 459 if (info->tft_alt_mode)
462 reg |= LCDC_TFT_ALT_ENABLE; 460 reg |= LCDC_TFT_ALT_ENABLE;
463 if (priv->rev == 2) { 461 if (priv->rev == 2) {
464 unsigned int depth, bpp; 462 switch (fb->pixel_format) {
465 463 case DRM_FORMAT_BGR565:
466 drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp); 464 case DRM_FORMAT_RGB565:
467 switch (bpp) {
468 case 16:
469 break; 465 break;
470 case 32: 466 case DRM_FORMAT_XBGR8888:
467 case DRM_FORMAT_XRGB8888:
471 reg |= LCDC_V2_TFT_24BPP_UNPACK; 468 reg |= LCDC_V2_TFT_24BPP_UNPACK;
472 /* fallthrough */ 469 /* fallthrough */
473 case 24: 470 case DRM_FORMAT_BGR888:
471 case DRM_FORMAT_RGB888:
474 reg |= LCDC_V2_TFT_24BPP_MODE; 472 reg |= LCDC_V2_TFT_24BPP_MODE;
475 break; 473 break;
476 default: 474 default:
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index a694977c32f4..147fb28287ae 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -143,8 +143,6 @@ static int tilcdc_commit(struct drm_device *dev,
143 143
144 drm_atomic_helper_cleanup_planes(dev, state); 144 drm_atomic_helper_cleanup_planes(dev, state);
145 145
146 drm_atomic_state_free(state);
147
148 return 0; 146 return 0;
149} 147}
150 148
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_plane.c b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
index 74c65fa859b2..8a6a50d74aff 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_plane.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
@@ -39,7 +39,7 @@ static int tilcdc_plane_atomic_check(struct drm_plane *plane,
39{ 39{
40 struct drm_crtc_state *crtc_state; 40 struct drm_crtc_state *crtc_state;
41 struct drm_plane_state *old_state = plane->state; 41 struct drm_plane_state *old_state = plane->state;
42 unsigned int depth, bpp; 42 unsigned int pitch;
43 43
44 if (!state->crtc) 44 if (!state->crtc)
45 return 0; 45 return 0;
@@ -68,8 +68,9 @@ static int tilcdc_plane_atomic_check(struct drm_plane *plane,
68 return -EINVAL; 68 return -EINVAL;
69 } 69 }
70 70
71 drm_fb_get_bpp_depth(state->fb->pixel_format, &depth, &bpp); 71 pitch = crtc_state->mode.hdisplay *
72 if (state->fb->pitches[0] != crtc_state->mode.hdisplay * bpp / 8) { 72 drm_format_plane_cpp(state->fb->pixel_format, 0);
73 if (state->fb->pitches[0] != pitch) {
73 dev_err(plane->dev->dev, 74 dev_err(plane->dev->dev,
74 "Invalid pitch: fb and crtc widths must be the same"); 75 "Invalid pitch: fb and crtc widths must be the same");
75 return -EINVAL; 76 return -EINVAL;
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index c1f65c6c8e60..f31f72af8551 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -61,7 +61,7 @@ vc4_atomic_complete_commit(struct vc4_commit *c)
61 61
62 drm_atomic_helper_cleanup_planes(dev, state); 62 drm_atomic_helper_cleanup_planes(dev, state);
63 63
64 drm_atomic_state_free(state); 64 drm_atomic_state_put(state);
65 65
66 up(&vc4->async_modeset); 66 up(&vc4->async_modeset);
67 67
@@ -173,6 +173,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
173 * current layout. 173 * current layout.
174 */ 174 */
175 175
176 drm_atomic_state_get(state);
176 if (nonblock) { 177 if (nonblock) {
177 vc4_queue_seqno_cb(dev, &c->cb, wait_seqno, 178 vc4_queue_seqno_cb(dev, &c->cb, wait_seqno,
178 vc4_atomic_complete_commit_seqno_cb); 179 vc4_atomic_complete_commit_seqno_cb);
diff --git a/drivers/gpu/drm/virtio/Kconfig b/drivers/gpu/drm/virtio/Kconfig
index e1afc3d3f8d9..81d1807ac228 100644
--- a/drivers/gpu/drm/virtio/Kconfig
+++ b/drivers/gpu/drm/virtio/Kconfig
@@ -1,10 +1,10 @@
1config DRM_VIRTIO_GPU 1config DRM_VIRTIO_GPU
2 tristate "Virtio GPU driver" 2 tristate "Virtio GPU driver"
3 depends on DRM && VIRTIO 3 depends on DRM && VIRTIO
4 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
5 select DRM_TTM 5 select DRM_TTM
6 help 6 help
7 This is the virtual GPU driver for virtio. It can be used with 7 This is the virtual GPU driver for virtio. It can be used with
8 QEMU based VMMs (like KVM or Xen). 8 QEMU based VMMs (like KVM or Xen).
9 9
10 If unsure say M. 10 If unsure say M.
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index bf28ccc150df..c965514b82be 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -980,14 +980,22 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
980 struct vmw_dma_buffer *bo = NULL; 980 struct vmw_dma_buffer *bo = NULL;
981 struct ttm_base_object *user_obj; 981 struct ttm_base_object *user_obj;
982 struct drm_mode_fb_cmd mode_cmd; 982 struct drm_mode_fb_cmd mode_cmd;
983 const struct drm_format_info *info;
983 int ret; 984 int ret;
984 985
986 info = drm_format_info(mode_cmd2->pixel_format);
987 if (!info || !info->depth) {
988 DRM_ERROR("Unsupported framebuffer format %s\n",
989 drm_get_format_name(mode_cmd2->pixel_format));
990 return ERR_PTR(-EINVAL);
991 }
992
985 mode_cmd.width = mode_cmd2->width; 993 mode_cmd.width = mode_cmd2->width;
986 mode_cmd.height = mode_cmd2->height; 994 mode_cmd.height = mode_cmd2->height;
987 mode_cmd.pitch = mode_cmd2->pitches[0]; 995 mode_cmd.pitch = mode_cmd2->pitches[0];
988 mode_cmd.handle = mode_cmd2->handles[0]; 996 mode_cmd.handle = mode_cmd2->handles[0];
989 drm_fb_get_bpp_depth(mode_cmd2->pixel_format, &mode_cmd.depth, 997 mode_cmd.depth = info->depth;
990 &mode_cmd.bpp); 998 mode_cmd.bpp = info->cpp[0] * 8;
991 999
992 /** 1000 /**
993 * This code should be conditioned on Screen Objects not being used. 1001 * This code should be conditioned on Screen Objects not being used.
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 52ca1c9d070e..1a85fb2d4dc6 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -575,7 +575,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo,
575 long lret; 575 long lret;
576 576
577 lret = reservation_object_wait_timeout_rcu(bo->resv, true, true, 577 lret = reservation_object_wait_timeout_rcu(bo->resv, true, true,
578 nonblock ? 0 : MAX_SCHEDULE_TIMEOUT); 578 nonblock ? 0 : MAX_SCHEDULE_TIMEOUT);
579 if (!lret) 579 if (!lret)
580 return -EBUSY; 580 return -EBUSY;
581 else if (lret < 0) 581 else if (lret < 0)
diff --git a/drivers/gpu/ipu-v3/Kconfig b/drivers/gpu/ipu-v3/Kconfig
index aefdff95356d..08766c6e7856 100644
--- a/drivers/gpu/ipu-v3/Kconfig
+++ b/drivers/gpu/ipu-v3/Kconfig
@@ -1,7 +1,6 @@
1config IMX_IPUV3_CORE 1config IMX_IPUV3_CORE
2 tristate "IPUv3 core support" 2 tristate "IPUv3 core support"
3 depends on SOC_IMX5 || SOC_IMX6Q || ARCH_MULTIPLATFORM 3 depends on SOC_IMX5 || SOC_IMX6Q || ARCH_MULTIPLATFORM
4 depends on RESET_CONTROLLER
5 select GENERIC_IRQ_CHIP 4 select GENERIC_IRQ_CHIP
6 help 5 help
7 Choose this if you have a i.MX5/6 system and want to use the Image 6 Choose this if you have a i.MX5/6 system and want to use the Image
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 1887f199ccb7..77657a8c0cd4 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -1022,21 +1022,16 @@ static ssize_t vga_arb_write(struct file *file, const char __user *buf,
1022 1022
1023 unsigned int io_state; 1023 unsigned int io_state;
1024 1024
1025 char *kbuf, *curr_pos; 1025 char kbuf[64], *curr_pos;
1026 size_t remaining = count; 1026 size_t remaining = count;
1027 1027
1028 int ret_val; 1028 int ret_val;
1029 int i; 1029 int i;
1030 1030
1031 1031 if (count >= sizeof(kbuf))
1032 kbuf = kmalloc(count + 1, GFP_KERNEL); 1032 return -EINVAL;
1033 if (!kbuf) 1033 if (copy_from_user(kbuf, buf, count))
1034 return -ENOMEM;
1035
1036 if (copy_from_user(kbuf, buf, count)) {
1037 kfree(kbuf);
1038 return -EFAULT; 1034 return -EFAULT;
1039 }
1040 curr_pos = kbuf; 1035 curr_pos = kbuf;
1041 kbuf[count] = '\0'; /* Just to make sure... */ 1036 kbuf[count] = '\0'; /* Just to make sure... */
1042 1037
@@ -1259,11 +1254,9 @@ static ssize_t vga_arb_write(struct file *file, const char __user *buf,
1259 goto done; 1254 goto done;
1260 } 1255 }
1261 /* If we got here, the message written is not part of the protocol! */ 1256 /* If we got here, the message written is not part of the protocol! */
1262 kfree(kbuf);
1263 return -EPROTO; 1257 return -EPROTO;
1264 1258
1265done: 1259done:
1266 kfree(kbuf);
1267 return ret_val; 1260 return ret_val;
1268} 1261}
1269 1262
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 162689227a23..1cf907ecded4 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -533,6 +533,10 @@ hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect)
533 return "4:3"; 533 return "4:3";
534 case HDMI_PICTURE_ASPECT_16_9: 534 case HDMI_PICTURE_ASPECT_16_9:
535 return "16:9"; 535 return "16:9";
536 case HDMI_PICTURE_ASPECT_64_27:
537 return "64:27";
538 case HDMI_PICTURE_ASPECT_256_135:
539 return "256:135";
536 case HDMI_PICTURE_ASPECT_RESERVED: 540 case HDMI_PICTURE_ASPECT_RESERVED:
537 return "Reserved"; 541 return "Reserved";
538 } 542 }
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 9701f2dfb784..fc8af53b18aa 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -153,6 +153,7 @@ struct __drm_connnectors_state {
153 153
154/** 154/**
155 * struct drm_atomic_state - the global state object for atomic updates 155 * struct drm_atomic_state - the global state object for atomic updates
156 * @ref: count of all references to this state (will not be freed until zero)
156 * @dev: parent DRM device 157 * @dev: parent DRM device
157 * @allow_modeset: allow full modeset 158 * @allow_modeset: allow full modeset
158 * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics 159 * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
@@ -164,6 +165,8 @@ struct __drm_connnectors_state {
164 * @acquire_ctx: acquire context for this atomic modeset state update 165 * @acquire_ctx: acquire context for this atomic modeset state update
165 */ 166 */
166struct drm_atomic_state { 167struct drm_atomic_state {
168 struct kref ref;
169
167 struct drm_device *dev; 170 struct drm_device *dev;
168 bool allow_modeset : 1; 171 bool allow_modeset : 1;
169 bool legacy_cursor_update : 1; 172 bool legacy_cursor_update : 1;
@@ -193,7 +196,33 @@ static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
193struct drm_atomic_state * __must_check 196struct drm_atomic_state * __must_check
194drm_atomic_state_alloc(struct drm_device *dev); 197drm_atomic_state_alloc(struct drm_device *dev);
195void drm_atomic_state_clear(struct drm_atomic_state *state); 198void drm_atomic_state_clear(struct drm_atomic_state *state);
196void drm_atomic_state_free(struct drm_atomic_state *state); 199
200/**
201 * drm_atomic_state_get - acquire a reference to the atomic state
202 * @state: The atomic state
203 *
204 * Returns a new reference to the @state
205 */
206static inline struct drm_atomic_state *
207drm_atomic_state_get(struct drm_atomic_state *state)
208{
209 kref_get(&state->ref);
210 return state;
211}
212
213void __drm_atomic_state_free(struct kref *ref);
214
215/**
216 * drm_atomic_state_put - release a reference to the atomic state
217 * @state: The atomic state
218 *
219 * This releases a reference to @state which is freed after removing the
220 * final reference. No locking required and callable from any context.
221 */
222static inline void drm_atomic_state_put(struct drm_atomic_state *state)
223{
224 kref_put(&state->ref, __drm_atomic_state_free);
225}
197 226
198int __must_check 227int __must_check
199drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state); 228drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state);
@@ -365,8 +394,17 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
365 * 394 *
366 * To give drivers flexibility struct &drm_crtc_state has 3 booleans to track 395 * To give drivers flexibility struct &drm_crtc_state has 3 booleans to track
367 * whether the state CRTC changed enough to need a full modeset cycle: 396 * whether the state CRTC changed enough to need a full modeset cycle:
368 * connectors_changed, mode_changed and active_change. This helper simply 397 * connectors_changed, mode_changed and active_changed. This helper simply
369 * combines these three to compute the overall need for a modeset for @state. 398 * combines these three to compute the overall need for a modeset for @state.
399 *
400 * The atomic helper code sets these booleans, but drivers can and should
401 * change them appropriately to accurately represent whether a modeset is
402 * really needed. In general, drivers should avoid full modesets whenever
403 * possible.
404 *
405 * For example if the CRTC mode has changed, and the hardware is able to enact
406 * the requested mode change without going through a full modeset, the driver
407 * should clear mode_changed during its ->atomic_check.
370 */ 408 */
371static inline bool 409static inline bool
372drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state) 410drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state)
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index 36baa175de99..fd351924e1c5 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -47,8 +47,16 @@ struct drm_atomic_state;
47#define DRM_REFLECT_Y BIT(5) 47#define DRM_REFLECT_Y BIT(5)
48#define DRM_REFLECT_MASK (DRM_REFLECT_X | DRM_REFLECT_Y) 48#define DRM_REFLECT_MASK (DRM_REFLECT_X | DRM_REFLECT_Y)
49 49
50static inline bool drm_rotation_90_or_270(unsigned int rotation)
51{
52 return rotation & (DRM_ROTATE_90 | DRM_ROTATE_270);
53}
54
50struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, 55struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
51 unsigned int supported_rotations); 56 unsigned int supported_rotations);
57int drm_plane_create_rotation_property(struct drm_plane *plane,
58 unsigned int rotation,
59 unsigned int supported_rotations);
52unsigned int drm_rotation_simplify(unsigned int rotation, 60unsigned int drm_rotation_simplify(unsigned int rotation,
53 unsigned int supported_rotations); 61 unsigned int supported_rotations);
54 62
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 0aa292526567..284c1b3aec10 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -47,6 +47,7 @@
47#include <drm/drm_plane.h> 47#include <drm/drm_plane.h>
48#include <drm/drm_blend.h> 48#include <drm/drm_blend.h>
49#include <drm/drm_color_mgmt.h> 49#include <drm/drm_color_mgmt.h>
50#include <drm/drm_debugfs_crc.h>
50 51
51struct drm_device; 52struct drm_device;
52struct drm_mode_set; 53struct drm_mode_set;
@@ -116,6 +117,11 @@ struct drm_plane_helper_funcs;
116 * never return in a failure from the ->atomic_check callback. Userspace assumes 117 * never return in a failure from the ->atomic_check callback. Userspace assumes
117 * that a DPMS On will always succeed. In other words: @enable controls resource 118 * that a DPMS On will always succeed. In other words: @enable controls resource
118 * assignment, @active controls the actual hardware state. 119 * assignment, @active controls the actual hardware state.
120 *
121 * The three booleans active_changed, connectors_changed and mode_changed are
122 * intended to indicate whether a full modeset is needed, rather than strictly
123 * describing what has changed in a commit.
124 * See also: drm_atomic_crtc_needs_modeset()
119 */ 125 */
120struct drm_crtc_state { 126struct drm_crtc_state {
121 struct drm_crtc *crtc; 127 struct drm_crtc *crtc;
@@ -564,6 +570,30 @@ struct drm_crtc_funcs {
564 * before data structures are torndown. 570 * before data structures are torndown.
565 */ 571 */
566 void (*early_unregister)(struct drm_crtc *crtc); 572 void (*early_unregister)(struct drm_crtc *crtc);
573
574 /**
575 * @set_crc_source:
576 *
577 * Changes the source of CRC checksums of frames at the request of
578 * userspace, typically for testing purposes. The sources available are
579 * specific of each driver and a %NULL value indicates that CRC
580 * generation is to be switched off.
581 *
582 * When CRC generation is enabled, the driver should call
583 * drm_crtc_add_crc_entry() at each frame, providing any information
584 * that characterizes the frame contents in the crcN arguments, as
585 * provided from the configured source. Drivers must accept a "auto"
586 * source name that will select a default source for this CRTC.
587 *
588 * This callback is optional if the driver does not support any CRC
589 * generation functionality.
590 *
591 * RETURNS:
592 *
593 * 0 on success or a negative error code on failure.
594 */
595 int (*set_crc_source)(struct drm_crtc *crtc, const char *source,
596 size_t *values_cnt);
567}; 597};
568 598
569/** 599/**
@@ -680,6 +710,22 @@ struct drm_crtc {
680 * context. 710 * context.
681 */ 711 */
682 struct drm_modeset_acquire_ctx *acquire_ctx; 712 struct drm_modeset_acquire_ctx *acquire_ctx;
713
714#ifdef CONFIG_DEBUG_FS
715 /**
716 * @debugfs_entry:
717 *
718 * Debugfs directory for this CRTC.
719 */
720 struct dentry *debugfs_entry;
721
722 /**
723 * @crc:
724 *
725 * Configuration settings of CRC capture.
726 */
727 struct drm_crtc_crc crc;
728#endif
683}; 729};
684 730
685/** 731/**
@@ -1354,7 +1400,7 @@ static inline unsigned int drm_crtc_index(const struct drm_crtc *crtc)
1354 * Given a registered CRTC, return the mask bit of that CRTC for an 1400 * Given a registered CRTC, return the mask bit of that CRTC for an
1355 * encoder's possible_crtcs field. 1401 * encoder's possible_crtcs field.
1356 */ 1402 */
1357static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc) 1403static inline uint32_t drm_crtc_mask(const struct drm_crtc *crtc)
1358{ 1404{
1359 return 1 << drm_crtc_index(crtc); 1405 return 1 << drm_crtc_index(crtc);
1360} 1406}
diff --git a/include/drm/drm_debugfs_crc.h b/include/drm/drm_debugfs_crc.h
new file mode 100644
index 000000000000..7d63b1d4adb9
--- /dev/null
+++ b/include/drm/drm_debugfs_crc.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright © 2016 Collabora Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22#ifndef __DRM_DEBUGFS_CRC_H__
23#define __DRM_DEBUGFS_CRC_H__
24
25#define DRM_MAX_CRC_NR 10
26
27/**
28 * struct drm_crtc_crc_entry - entry describing a frame's content
29 * @has_frame_counter: whether the source was able to provide a frame number
30 * @frame: number of the frame this CRC is about, if @has_frame_counter is true
31 * @crc: array of values that characterize the frame
32 */
33struct drm_crtc_crc_entry {
34 bool has_frame_counter;
35 uint32_t frame;
36 uint32_t crcs[DRM_MAX_CRC_NR];
37};
38
39#define DRM_CRC_ENTRIES_NR 128
40
41/**
42 * struct drm_crtc_crc - data supporting CRC capture on a given CRTC
43 * @lock: protects the fields in this struct
44 * @source: name of the currently configured source of CRCs
45 * @opened: whether userspace has opened the data file for reading
46 * @entries: array of entries, with size of %DRM_CRC_ENTRIES_NR
47 * @head: head of circular queue
48 * @tail: tail of circular queue
49 * @values_cnt: number of CRC values per entry, up to %DRM_MAX_CRC_NR
50 * @wq: workqueue used to synchronize reading and writing
51 */
52struct drm_crtc_crc {
53 spinlock_t lock;
54 const char *source;
55 bool opened;
56 struct drm_crtc_crc_entry *entries;
57 int head, tail;
58 size_t values_cnt;
59 wait_queue_head_t wq;
60};
61
62#if defined(CONFIG_DEBUG_FS)
63int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,
64 uint32_t frame, uint32_t *crcs);
65#else
66static inline int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,
67 uint32_t frame, uint32_t *crcs)
68{
69 return -EINVAL;
70}
71#endif /* defined(CONFIG_DEBUG_FS) */
72
73#endif /* __DRM_DEBUGFS_CRC_H__ */
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 387e33a4d6ee..c7438ff0d609 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -189,7 +189,7 @@ static inline unsigned int drm_encoder_index(struct drm_encoder *encoder)
189} 189}
190 190
191/* FIXME: We have an include file mess still, drm_crtc.h needs untangling. */ 191/* FIXME: We have an include file mess still, drm_crtc.h needs untangling. */
192static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc); 192static inline uint32_t drm_crtc_mask(const struct drm_crtc *crtc);
193 193
194/** 194/**
195 * drm_encoder_crtc_ok - can a given crtc drive a given encoder? 195 * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 30c30fa87ee8..dc0aafab9ffd 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -25,8 +25,29 @@
25#include <linux/types.h> 25#include <linux/types.h>
26#include <uapi/drm/drm_fourcc.h> 26#include <uapi/drm/drm_fourcc.h>
27 27
28/**
29 * struct drm_format_info - information about a DRM format
30 * @format: 4CC format identifier (DRM_FORMAT_*)
31 * @depth: Color depth (number of bits per pixel excluding padding bits),
32 * valid for a subset of RGB formats only. This is a legacy field, do not
33 * use in new code and set to 0 for new formats.
34 * @num_planes: Number of color planes (1 to 3)
35 * @cpp: Number of bytes per pixel (per plane)
36 * @hsub: Horizontal chroma subsampling factor
37 * @vsub: Vertical chroma subsampling factor
38 */
39struct drm_format_info {
40 u32 format;
41 u8 depth;
42 u8 num_planes;
43 u8 cpp[3];
44 u8 hsub;
45 u8 vsub;
46};
47
48const struct drm_format_info *__drm_format_info(u32 format);
49const struct drm_format_info *drm_format_info(u32 format);
28uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); 50uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
29void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp);
30int drm_format_num_planes(uint32_t format); 51int drm_format_num_planes(uint32_t format);
31int drm_format_plane_cpp(uint32_t format, int plane); 52int drm_format_plane_cpp(uint32_t format, int plane);
32int drm_format_horz_chroma_subsampling(uint32_t format); 53int drm_format_horz_chroma_subsampling(uint32_t format);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 43cf193e54d6..98b39d66eb32 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -88,7 +88,6 @@ struct drm_plane_state {
88 struct drm_atomic_state *state; 88 struct drm_atomic_state *state;
89}; 89};
90 90
91
92/** 91/**
93 * struct drm_plane_funcs - driver plane control functions 92 * struct drm_plane_funcs - driver plane control functions
94 */ 93 */
@@ -386,6 +385,7 @@ enum drm_plane_type {
386 * @type: type of plane (overlay, primary, cursor) 385 * @type: type of plane (overlay, primary, cursor)
387 * @state: current atomic state for this plane 386 * @state: current atomic state for this plane
388 * @zpos_property: zpos property for this plane 387 * @zpos_property: zpos property for this plane
388 * @rotation_property: rotation property for this plane
389 * @helper_private: mid-layer private data 389 * @helper_private: mid-layer private data
390 */ 390 */
391struct drm_plane { 391struct drm_plane {
@@ -432,6 +432,7 @@ struct drm_plane {
432 struct drm_plane_state *state; 432 struct drm_plane_state *state;
433 433
434 struct drm_property *zpos_property; 434 struct drm_property *zpos_property;
435 struct drm_property *rotation_property;
435}; 436};
436 437
437#define obj_to_plane(x) container_of(x, struct drm_plane, base) 438#define obj_to_plane(x) container_of(x, struct drm_plane, base)
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 0d763053f97a..c9c5ba98c302 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -183,6 +183,16 @@ void fence_release(struct kref *kref);
183void fence_free(struct fence *fence); 183void fence_free(struct fence *fence);
184 184
185/** 185/**
186 * fence_put - decreases refcount of the fence
187 * @fence: [in] fence to reduce refcount of
188 */
189static inline void fence_put(struct fence *fence)
190{
191 if (fence)
192 kref_put(&fence->refcount, fence_release);
193}
194
195/**
186 * fence_get - increases refcount of the fence 196 * fence_get - increases refcount of the fence
187 * @fence: [in] fence to increase refcount of 197 * @fence: [in] fence to increase refcount of
188 * 198 *
@@ -210,13 +220,49 @@ static inline struct fence *fence_get_rcu(struct fence *fence)
210} 220}
211 221
212/** 222/**
213 * fence_put - decreases refcount of the fence 223 * fence_get_rcu_safe - acquire a reference to an RCU tracked fence
214 * @fence: [in] fence to reduce refcount of 224 * @fence: [in] pointer to fence to increase refcount of
225 *
226 * Function returns NULL if no refcount could be obtained, or the fence.
227 * This function handles acquiring a reference to a fence that may be
228 * reallocated within the RCU grace period (such as with SLAB_DESTROY_BY_RCU),
229 * so long as the caller is using RCU on the pointer to the fence.
230 *
231 * An alternative mechanism is to employ a seqlock to protect a bunch of
232 * fences, such as used by struct reservation_object. When using a seqlock,
233 * the seqlock must be taken before and checked after a reference to the
234 * fence is acquired (as shown here).
235 *
236 * The caller is required to hold the RCU read lock.
215 */ 237 */
216static inline void fence_put(struct fence *fence) 238static inline struct fence *fence_get_rcu_safe(struct fence * __rcu *fencep)
217{ 239{
218 if (fence) 240 do {
219 kref_put(&fence->refcount, fence_release); 241 struct fence *fence;
242
243 fence = rcu_dereference(*fencep);
244 if (!fence || !fence_get_rcu(fence))
245 return NULL;
246
247 /* The atomic_inc_not_zero() inside fence_get_rcu()
248 * provides a full memory barrier upon success (such as now).
249 * This is paired with the write barrier from assigning
250 * to the __rcu protected fence pointer so that if that
251 * pointer still matches the current fence, we know we
252 * have successfully acquire a reference to it. If it no
253 * longer matches, we are holding a reference to some other
254 * reallocated pointer. This is possible if the allocator
255 * is using a freelist like SLAB_DESTROY_BY_RCU where the
256 * fence remains valid for the RCU grace period, but it
257 * may be reallocated. When using such allocators, we are
258 * responsible for ensuring the reference we get is to
259 * the right fence, as below.
260 */
261 if (fence == rcu_access_pointer(*fencep))
262 return rcu_pointer_handoff(fence);
263
264 fence_put(fence);
265 } while (1);
220} 266}
221 267
222int fence_signal(struct fence *fence); 268int fence_signal(struct fence *fence);
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index e9744202fa29..edbb4fc674ed 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -78,6 +78,8 @@ enum hdmi_picture_aspect {
78 HDMI_PICTURE_ASPECT_NONE, 78 HDMI_PICTURE_ASPECT_NONE,
79 HDMI_PICTURE_ASPECT_4_3, 79 HDMI_PICTURE_ASPECT_4_3,
80 HDMI_PICTURE_ASPECT_16_9, 80 HDMI_PICTURE_ASPECT_16_9,
81 HDMI_PICTURE_ASPECT_64_27,
82 HDMI_PICTURE_ASPECT_256_135,
81 HDMI_PICTURE_ASPECT_RESERVED, 83 HDMI_PICTURE_ASPECT_RESERVED,
82}; 84};
83 85
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index df0e3504c349..084b50a02dc5 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -77,6 +77,25 @@ extern "C" {
77#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14) 77#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14)
78#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14) 78#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14)
79 79
80/* Picture aspect ratio options */
81#define DRM_MODE_PICTURE_ASPECT_NONE 0
82#define DRM_MODE_PICTURE_ASPECT_4_3 1
83#define DRM_MODE_PICTURE_ASPECT_16_9 2
84#define DRM_MODE_PICTURE_ASPECT_64_27 3
85#define DRM_MODE_PICTURE_ASPECT_256_135 4
86
87/* Aspect ratio flag bitmask (4 bits 22:19) */
88#define DRM_MODE_FLAG_PIC_AR_MASK (0x0F<<19)
89#define DRM_MODE_FLAG_PIC_AR_NONE \
90 (DRM_MODE_PICTURE_ASPECT_NONE<<19)
91#define DRM_MODE_FLAG_PIC_AR_4_3 \
92 (DRM_MODE_PICTURE_ASPECT_4_3<<19)
93#define DRM_MODE_FLAG_PIC_AR_16_9 \
94 (DRM_MODE_PICTURE_ASPECT_16_9<<19)
95#define DRM_MODE_FLAG_PIC_AR_64_27 \
96 (DRM_MODE_PICTURE_ASPECT_64_27<<19)
97#define DRM_MODE_FLAG_PIC_AR_256_135 \
98 (DRM_MODE_PICTURE_ASPECT_256_135<<19)
80 99
81/* DPMS flags */ 100/* DPMS flags */
82/* bit compatible with the xorg definitions. */ 101/* bit compatible with the xorg definitions. */
@@ -92,11 +111,6 @@ extern "C" {
92#define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */ 111#define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */
93#define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */ 112#define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */
94 113
95/* Picture aspect ratio options */
96#define DRM_MODE_PICTURE_ASPECT_NONE 0
97#define DRM_MODE_PICTURE_ASPECT_4_3 1
98#define DRM_MODE_PICTURE_ASPECT_16_9 2
99
100/* Dithering mode options */ 114/* Dithering mode options */
101#define DRM_MODE_DITHERING_OFF 0 115#define DRM_MODE_DITHERING_OFF 0
102#define DRM_MODE_DITHERING_ON 1 116#define DRM_MODE_DITHERING_ON 1