diff options
author | Dave Airlie <airlied@redhat.com> | 2016-10-25 02:35:20 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-10-25 02:35:20 -0400 |
commit | 61d0a04d6f5b2122f88aacbc4b1716e571961660 (patch) | |
tree | 1f7f775b4b8f1b04144bb35b569db73eaf890eee | |
parent | 07d9a380680d1c0eb51ef87ff2eab5c994949e69 (diff) | |
parent | 8a5bbf327aa16025c78491266a6425807c7fbee0 (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()
...
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 | |||
63 | DRM Format Handling | 63 | DRM 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 | |||
216 | userspace are driver specific for efficiency and other reasons these | 216 | userspace are driver specific for efficiency and other reasons these |
217 | interfaces can be rather substantial. Hence every driver has its own | 217 | interfaces can be rather substantial. Hence every driver has its own |
218 | chapter. | 218 | chapter. |
219 | |||
220 | Testing 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; | ||
348 | unlock: | 338 | unlock: |
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(); | ||
489 | retry: | 480 | retry: |
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 | |||
541 | unlock_retry: | ||
542 | rcu_read_unlock(); | ||
543 | goto retry; | ||
544 | } | 524 | } |
545 | EXPORT_SYMBOL_GPL(reservation_object_test_signaled_rcu); | 525 | EXPORT_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 | |||
23 | drm-$(CONFIG_DRM_PANEL) += drm_panel.o | 23 | drm-$(CONFIG_DRM_PANEL) += drm_panel.o |
24 | drm-$(CONFIG_OF) += drm_of.o | 24 | drm-$(CONFIG_OF) += drm_of.o |
25 | drm-$(CONFIG_AGP) += drm_agpsupport.o | 25 | drm-$(CONFIG_AGP) += drm_agpsupport.o |
26 | drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o | ||
26 | 27 | ||
27 | drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ | 28 | drm_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 | ||
93 | int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tiled) | 93 | int 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 | ||
116 | static void amdgpufb_destroy_pinned_object(struct drm_gem_object *gobj) | 116 | static 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 | ||
199 | static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt) | 199 | static 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 | ||
218 | static int malidp550_query_hw(struct malidp_hw_device *hwdev) | 213 | static 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 | ||
886 | static void atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane, | 886 | static 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 | ||
930 | static struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = { | 940 | static 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); | |||
74 | int | 74 | int |
75 | drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state) | 75 | drm_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) | |||
215 | EXPORT_SYMBOL(drm_atomic_state_clear); | 217 | EXPORT_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 | */ |
224 | void drm_atomic_state_free(struct drm_atomic_state *state) | 226 | void __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 | } |
246 | EXPORT_SYMBOL(drm_atomic_state_free); | 242 | EXPORT_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 | ||
1213 | static void commit_work(struct work_struct *work) | 1214 | static 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; | ||
2121 | fail: | 2118 | fail: |
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 | |||
2128 | backoff: | 2125 | backoff: |
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; | ||
2194 | fail: | 2186 | fail: |
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 | |||
2201 | backoff: | 2193 | backoff: |
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; | ||
2334 | fail: | 2321 | fail: |
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 | |||
2341 | backoff: | 2328 | backoff: |
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 | |||
2483 | free: | 2469 | free: |
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 | } |
2489 | EXPORT_SYMBOL(drm_atomic_helper_disable_all); | 2473 | EXPORT_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; | ||
2631 | fail: | 2610 | fail: |
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 | |||
2638 | backoff: | 2617 | backoff: |
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; | ||
2691 | fail: | 2665 | fail: |
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 | |||
2698 | backoff: | 2672 | backoff: |
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; | ||
2751 | fail: | 2720 | fail: |
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 | |||
2758 | backoff: | 2727 | backoff: |
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; | ||
2835 | fail: | 2799 | fail: |
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 | |||
2842 | backoff: | 2806 | backoff: |
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; | ||
2922 | fail: | 2881 | fail: |
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 | |||
2930 | backoff: | 2889 | backoff: |
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 | ||
3334 | free: | 3293 | free: |
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; | ||
3459 | fail: | 3410 | fail: |
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 | |||
3467 | backoff: | 3418 | backoff: |
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 | } |
163 | EXPORT_SYMBOL(drm_mode_create_rotation_property); | 163 | EXPORT_SYMBOL(drm_mode_create_rotation_property); |
164 | 164 | ||
165 | int 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 | } | ||
198 | EXPORT_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 | ||
149 | static 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 | |||
161 | static 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 */ | 418 | int 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 | |||
440 | error: | ||
441 | drm_debugfs_crtc_remove(crtc); | ||
442 | return -ENOMEM; | ||
443 | } | ||
444 | |||
445 | void 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 | |||
62 | static 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 | |||
71 | static 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 | |||
78 | static 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 | |||
119 | static 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 | |||
128 | static 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 | |||
167 | err_disable: | ||
168 | crtc->funcs->set_crc_source(crtc, NULL, &values_cnt); | ||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | static 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 | |||
192 | static 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 | |||
205 | static 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 | |||
265 | static 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 | */ | ||
282 | int 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 | |||
305 | error: | ||
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 | */ | ||
321 | int 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 | } | ||
352 | EXPORT_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 | ||
1350 | carp: | 1348 | carp: |
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 | ||
1357 | out: | 1355 | out: |
1358 | kfree(block); | 1356 | kfree(edid); |
1359 | return NULL; | 1357 | return NULL; |
1360 | } | 1358 | } |
1361 | EXPORT_SYMBOL_GPL(drm_do_get_edid); | 1359 | EXPORT_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); | |||
269 | static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m) | 269 | static 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); | |||
557 | void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma) | 560 | void 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 | ||
375 | backoff: | 373 | backoff: |
@@ -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 | |||
1365 | fail: | 1369 | fail: |
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 | ||
1376 | backoff: | 1378 | backoff: |
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 | } |
668 | EXPORT_SYMBOL(drm_event_cancel_free); | 672 | EXPORT_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 | } |
103 | EXPORT_SYMBOL(drm_get_format_name); | 103 | EXPORT_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 | */ | ||
109 | const 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 | */ |
114 | void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, | 195 | const 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 | } |
181 | EXPORT_SYMBOL(drm_fb_get_bpp_depth); | 203 | EXPORT_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 | */ |
190 | int drm_format_num_planes(uint32_t format) | 212 | int 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 | } |
215 | EXPORT_SYMBOL(drm_format_num_planes); | 219 | EXPORT_SYMBOL(drm_format_num_planes); |
216 | 220 | ||
@@ -224,40 +228,13 @@ EXPORT_SYMBOL(drm_format_num_planes); | |||
224 | */ | 228 | */ |
225 | int drm_format_plane_cpp(uint32_t format, int plane) | 229 | int 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 | } |
262 | EXPORT_SYMBOL(drm_format_plane_cpp); | 239 | EXPORT_SYMBOL(drm_format_plane_cpp); |
263 | 240 | ||
@@ -271,28 +248,10 @@ EXPORT_SYMBOL(drm_format_plane_cpp); | |||
271 | */ | 248 | */ |
272 | int drm_format_horz_chroma_subsampling(uint32_t format) | 249 | int 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 | } |
297 | EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); | 256 | EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); |
298 | 257 | ||
@@ -306,18 +265,10 @@ EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); | |||
306 | */ | 265 | */ |
307 | int drm_format_vert_chroma_subsampling(uint32_t format) | 266 | int 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 | } |
322 | EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); | 273 | EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); |
323 | 274 | ||
@@ -332,13 +283,16 @@ EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); | |||
332 | */ | 283 | */ |
333 | int drm_format_plane_width(int width, uint32_t format, int plane) | 284 | int 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 | } |
343 | EXPORT_SYMBOL(drm_format_plane_width); | 297 | EXPORT_SYMBOL(drm_format_plane_width); |
344 | 298 | ||
@@ -353,12 +307,15 @@ EXPORT_SYMBOL(drm_format_plane_width); | |||
353 | */ | 307 | */ |
354 | int drm_format_plane_height(int height, uint32_t format, int plane) | 308 | int 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 | } |
364 | EXPORT_SYMBOL(drm_format_plane_height); | 321 | EXPORT_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 | ||
129 | static 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 | |||
204 | static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) | 129 | static 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, | |||
100 | int drm_debugfs_cleanup(struct drm_minor *minor); | 100 | int drm_debugfs_cleanup(struct drm_minor *minor); |
101 | int drm_debugfs_connector_add(struct drm_connector *connector); | 101 | int drm_debugfs_connector_add(struct drm_connector *connector); |
102 | void drm_debugfs_connector_remove(struct drm_connector *connector); | 102 | void drm_debugfs_connector_remove(struct drm_connector *connector); |
103 | int drm_debugfs_crtc_add(struct drm_crtc *crtc); | ||
104 | void drm_debugfs_crtc_remove(struct drm_crtc *crtc); | ||
105 | int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc); | ||
103 | #else | 106 | #else |
104 | static inline int drm_debugfs_init(struct drm_minor *minor, int minor_id, | 107 | static 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) | |||
119 | static inline void drm_debugfs_connector_remove(struct drm_connector *connector) | 122 | static inline void drm_debugfs_connector_remove(struct drm_connector *connector) |
120 | { | 123 | { |
121 | } | 124 | } |
125 | |||
126 | static inline int drm_debugfs_crtc_add(struct drm_crtc *crtc) | ||
127 | { | ||
128 | return 0; | ||
129 | } | ||
130 | static inline void drm_debugfs_crtc_remove(struct drm_crtc *crtc) | ||
131 | { | ||
132 | } | ||
133 | |||
134 | static 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); | |||
70 | void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, | 70 | void 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); |
3943 | out: | 3943 | out: |
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 | ||
3950 | static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, | 3949 | static 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) | |||
2260 | static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane, | 2260 | static 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 | ||
3586 | err: | 3586 | err: |
3587 | drm_atomic_state_free(state); | 3587 | drm_atomic_state_put(state); |
3588 | } | 3588 | } |
3589 | 3589 | ||
3590 | void intel_finish_reset(struct drm_i915_private *dev_priv) | 3590 | void 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 | ||
11272 | fail: | 11274 | fail: |
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 | ||
11309 | static int i9xx_pll_refclk(struct drm_device *dev, | 11315 | static 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) | ||
14585 | out: | 14590 | out: |
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 | ||
14990 | void 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 | |||
15008 | static int | 15009 | static int |
15009 | intel_check_cursor_plane(struct drm_plane *plane, | 15010 | intel_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); | 16323 | put_state: |
16324 | drm_atomic_state_put(state); | ||
16329 | fail: | 16325 | fail: |
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 | ||
16972 | void intel_modeset_gem_init(struct drm_device *dev) | 16967 | void 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, | |||
1285 | unsigned int intel_tile_height(const struct drm_i915_private *dev_priv, | 1285 | unsigned 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 | ||
1288 | static inline bool | ||
1289 | intel_rotation_90_or_270(unsigned int rotation) | ||
1290 | { | ||
1291 | return rotation & (DRM_ROTATE_90 | DRM_ROTATE_270); | ||
1292 | } | ||
1293 | |||
1294 | void intel_create_rotation_property(struct drm_device *dev, | ||
1295 | struct intel_plane *plane); | ||
1296 | |||
1297 | void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, | 1288 | void 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 | |||
993 | out: | 991 | out: |
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 | ||
89 | static void mtk_atomic_work(struct work_struct *work) | 89 | static 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 | ||
441 | static bool omap_crtc_is_plane_prop(struct drm_device *dev, | 441 | static 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 | ||
450 | static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, | 451 | static 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 | ||
92 | int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) | 92 | int 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 | ||
116 | static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) | 116 | static 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 @@ | |||
1 | config DRM_ROCKCHIP | 1 | config 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 | ||
190 | static void sti_atomic_work(struct work_struct *work) | 190 | static 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 | ||
69 | static void tegra_atomic_work(struct work_struct *work) | 69 | static 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 @@ | |||
1 | config DRM_VIRTIO_GPU | 1 | config DRM_VIRTIO_GPU |
2 | tristate "Virtio GPU driver" | 2 | tristate "Virtio GPU driver" |
3 | depends on DRM && VIRTIO | 3 | depends on DRM && VIRTIO |
4 | select 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 @@ | |||
1 | config IMX_IPUV3_CORE | 1 | config 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 | ||
1265 | done: | 1259 | done: |
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 | */ |
166 | struct drm_atomic_state { | 167 | struct 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) | |||
193 | struct drm_atomic_state * __must_check | 196 | struct drm_atomic_state * __must_check |
194 | drm_atomic_state_alloc(struct drm_device *dev); | 197 | drm_atomic_state_alloc(struct drm_device *dev); |
195 | void drm_atomic_state_clear(struct drm_atomic_state *state); | 198 | void drm_atomic_state_clear(struct drm_atomic_state *state); |
196 | void 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 | */ | ||
206 | static inline struct drm_atomic_state * | ||
207 | drm_atomic_state_get(struct drm_atomic_state *state) | ||
208 | { | ||
209 | kref_get(&state->ref); | ||
210 | return state; | ||
211 | } | ||
212 | |||
213 | void __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 | */ | ||
222 | static inline void drm_atomic_state_put(struct drm_atomic_state *state) | ||
223 | { | ||
224 | kref_put(&state->ref, __drm_atomic_state_free); | ||
225 | } | ||
197 | 226 | ||
198 | int __must_check | 227 | int __must_check |
199 | drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state); | 228 | drm_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 | */ |
371 | static inline bool | 409 | static inline bool |
372 | drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state) | 410 | drm_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 | ||
50 | static inline bool drm_rotation_90_or_270(unsigned int rotation) | ||
51 | { | ||
52 | return rotation & (DRM_ROTATE_90 | DRM_ROTATE_270); | ||
53 | } | ||
54 | |||
50 | struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, | 55 | struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, |
51 | unsigned int supported_rotations); | 56 | unsigned int supported_rotations); |
57 | int drm_plane_create_rotation_property(struct drm_plane *plane, | ||
58 | unsigned int rotation, | ||
59 | unsigned int supported_rotations); | ||
52 | unsigned int drm_rotation_simplify(unsigned int rotation, | 60 | unsigned 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 | ||
51 | struct drm_device; | 52 | struct drm_device; |
52 | struct drm_mode_set; | 53 | struct 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 | */ |
120 | struct drm_crtc_state { | 126 | struct 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 | */ |
1357 | static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc) | 1403 | static 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 | */ | ||
33 | struct 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 | */ | ||
52 | struct 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) | ||
63 | int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, | ||
64 | uint32_t frame, uint32_t *crcs); | ||
65 | #else | ||
66 | static 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. */ |
192 | static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc); | 192 | static 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 | */ | ||
39 | struct 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 | |||
48 | const struct drm_format_info *__drm_format_info(u32 format); | ||
49 | const struct drm_format_info *drm_format_info(u32 format); | ||
28 | uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); | 50 | uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); |
29 | void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp); | ||
30 | int drm_format_num_planes(uint32_t format); | 51 | int drm_format_num_planes(uint32_t format); |
31 | int drm_format_plane_cpp(uint32_t format, int plane); | 52 | int drm_format_plane_cpp(uint32_t format, int plane); |
32 | int drm_format_horz_chroma_subsampling(uint32_t format); | 53 | int 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 | */ |
391 | struct drm_plane { | 391 | struct 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); | |||
183 | void fence_free(struct fence *fence); | 183 | void 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 | */ | ||
189 | static 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 | */ |
216 | static inline void fence_put(struct fence *fence) | 238 | static 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 | ||
222 | int fence_signal(struct fence *fence); | 268 | int 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 |