1
1
// SPDX-License-Identifier: GPL-2.0 OR MIT
2
2
/**************************************************************************
3
3
*
4
- * Copyright © 2011-2023 VMware, Inc., Palo Alto, CA., USA
5
- * All Rights Reserved .
4
+ * Copyright (c) 2011-2024 Broadcom. All Rights Reserved. The term
5
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries .
6
6
*
7
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
8
* copy of this software and associated documentation files (the
28
28
29
29
#include "vmwgfx_bo.h"
30
30
#include "vmwgfx_drv.h"
31
-
31
+ #include "vmwgfx_resource_priv.h"
32
32
33
33
#include <drm/ttm/ttm_placement.h>
34
34
35
35
static void vmw_bo_release (struct vmw_bo * vbo )
36
36
{
37
+ struct vmw_resource * res ;
38
+
37
39
WARN_ON (vbo -> tbo .base .funcs &&
38
40
kref_read (& vbo -> tbo .base .refcount ) != 0 );
39
41
vmw_bo_unmap (vbo );
42
+
43
+ xa_destroy (& vbo -> detached_resources );
44
+ WARN_ON (vbo -> is_dumb && !vbo -> dumb_surface );
45
+ if (vbo -> is_dumb && vbo -> dumb_surface ) {
46
+ res = & vbo -> dumb_surface -> res ;
47
+ WARN_ON (vbo != res -> guest_memory_bo );
48
+ WARN_ON (!res -> guest_memory_bo );
49
+ if (res -> guest_memory_bo ) {
50
+ /* Reserve and switch the backing mob. */
51
+ mutex_lock (& res -> dev_priv -> cmdbuf_mutex );
52
+ (void )vmw_resource_reserve (res , false, true);
53
+ vmw_resource_mob_detach (res );
54
+ if (res -> coherent )
55
+ vmw_bo_dirty_release (res -> guest_memory_bo );
56
+ res -> guest_memory_bo = NULL ;
57
+ res -> guest_memory_offset = 0 ;
58
+ vmw_resource_unreserve (res , false, false, false, NULL ,
59
+ 0 );
60
+ mutex_unlock (& res -> dev_priv -> cmdbuf_mutex );
61
+ }
62
+ vmw_surface_unreference (& vbo -> dumb_surface );
63
+ }
40
64
drm_gem_object_release (& vbo -> tbo .base );
41
65
}
42
66
@@ -325,6 +349,11 @@ void vmw_bo_pin_reserved(struct vmw_bo *vbo, bool pin)
325
349
*
326
350
*/
327
351
void * vmw_bo_map_and_cache (struct vmw_bo * vbo )
352
+ {
353
+ return vmw_bo_map_and_cache_size (vbo , vbo -> tbo .base .size );
354
+ }
355
+
356
+ void * vmw_bo_map_and_cache_size (struct vmw_bo * vbo , size_t size )
328
357
{
329
358
struct ttm_buffer_object * bo = & vbo -> tbo ;
330
359
bool not_used ;
@@ -335,9 +364,10 @@ void *vmw_bo_map_and_cache(struct vmw_bo *vbo)
335
364
if (virtual )
336
365
return virtual ;
337
366
338
- ret = ttm_bo_kmap (bo , 0 , PFN_UP (bo -> base . size ), & vbo -> map );
367
+ ret = ttm_bo_kmap (bo , 0 , PFN_UP (size ), & vbo -> map );
339
368
if (ret )
340
- DRM_ERROR ("Buffer object map failed: %d.\n" , ret );
369
+ DRM_ERROR ("Buffer object map failed: %d (size: bo = %zu, map = %zu).\n" ,
370
+ ret , bo -> base .size , size );
341
371
342
372
return ttm_kmap_obj_virtual (& vbo -> map , & not_used );
343
373
}
@@ -390,6 +420,7 @@ static int vmw_bo_init(struct vmw_private *dev_priv,
390
420
BUILD_BUG_ON (TTM_MAX_BO_PRIORITY <= 3 );
391
421
vmw_bo -> tbo .priority = 3 ;
392
422
vmw_bo -> res_tree = RB_ROOT ;
423
+ xa_init (& vmw_bo -> detached_resources );
393
424
394
425
params -> size = ALIGN (params -> size , PAGE_SIZE );
395
426
drm_gem_private_object_init (vdev , & vmw_bo -> tbo .base , params -> size );
@@ -654,52 +685,6 @@ void vmw_bo_fence_single(struct ttm_buffer_object *bo,
654
685
dma_fence_put (& fence -> base );
655
686
}
656
687
657
-
658
- /**
659
- * vmw_dumb_create - Create a dumb kms buffer
660
- *
661
- * @file_priv: Pointer to a struct drm_file identifying the caller.
662
- * @dev: Pointer to the drm device.
663
- * @args: Pointer to a struct drm_mode_create_dumb structure
664
- * Return: Zero on success, negative error code on failure.
665
- *
666
- * This is a driver callback for the core drm create_dumb functionality.
667
- * Note that this is very similar to the vmw_bo_alloc ioctl, except
668
- * that the arguments have a different format.
669
- */
670
- int vmw_dumb_create (struct drm_file * file_priv ,
671
- struct drm_device * dev ,
672
- struct drm_mode_create_dumb * args )
673
- {
674
- struct vmw_private * dev_priv = vmw_priv (dev );
675
- struct vmw_bo * vbo ;
676
- int cpp = DIV_ROUND_UP (args -> bpp , 8 );
677
- int ret ;
678
-
679
- switch (cpp ) {
680
- case 1 : /* DRM_FORMAT_C8 */
681
- case 2 : /* DRM_FORMAT_RGB565 */
682
- case 4 : /* DRM_FORMAT_XRGB8888 */
683
- break ;
684
- default :
685
- /*
686
- * Dumb buffers don't allow anything else.
687
- * This is tested via IGT's dumb_buffers
688
- */
689
- return - EINVAL ;
690
- }
691
-
692
- args -> pitch = args -> width * cpp ;
693
- args -> size = ALIGN (args -> pitch * args -> height , PAGE_SIZE );
694
-
695
- ret = vmw_gem_object_create_with_handle (dev_priv , file_priv ,
696
- args -> size , & args -> handle ,
697
- & vbo );
698
- /* drop reference from allocate - handle holds it now */
699
- drm_gem_object_put (& vbo -> tbo .base );
700
- return ret ;
701
- }
702
-
703
688
/**
704
689
* vmw_bo_swap_notify - swapout notify callback.
705
690
*
@@ -853,3 +838,43 @@ void vmw_bo_placement_set_default_accelerated(struct vmw_bo *bo)
853
838
854
839
vmw_bo_placement_set (bo , domain , domain );
855
840
}
841
+
842
+ void vmw_bo_add_detached_resource (struct vmw_bo * vbo , struct vmw_resource * res )
843
+ {
844
+ xa_store (& vbo -> detached_resources , (unsigned long )res , res , GFP_KERNEL );
845
+ }
846
+
847
+ void vmw_bo_del_detached_resource (struct vmw_bo * vbo , struct vmw_resource * res )
848
+ {
849
+ xa_erase (& vbo -> detached_resources , (unsigned long )res );
850
+ }
851
+
852
+ struct vmw_surface * vmw_bo_surface (struct vmw_bo * vbo )
853
+ {
854
+ unsigned long index ;
855
+ struct vmw_resource * res = NULL ;
856
+ struct vmw_surface * surf = NULL ;
857
+ struct rb_node * rb_itr = vbo -> res_tree .rb_node ;
858
+
859
+ if (vbo -> is_dumb && vbo -> dumb_surface ) {
860
+ res = & vbo -> dumb_surface -> res ;
861
+ goto out ;
862
+ }
863
+
864
+ xa_for_each (& vbo -> detached_resources , index , res ) {
865
+ if (res -> func -> res_type == vmw_res_surface )
866
+ goto out ;
867
+ }
868
+
869
+ for (rb_itr = rb_first (& vbo -> res_tree ); rb_itr ;
870
+ rb_itr = rb_next (rb_itr )) {
871
+ res = rb_entry (rb_itr , struct vmw_resource , mob_node );
872
+ if (res -> func -> res_type == vmw_res_surface )
873
+ goto out ;
874
+ }
875
+
876
+ out :
877
+ if (res )
878
+ surf = vmw_res_to_srf (res );
879
+ return surf ;
880
+ }
0 commit comments