35
35
#include <linux/slab.h>
36
36
#include <linux/srcu.h>
37
37
38
+ #include <drm/drm_accel.h>
38
39
#include <drm/drm_cache.h>
39
40
#include <drm/drm_client.h>
40
41
#include <drm/drm_color_mgmt.h>
@@ -90,6 +91,8 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
90
91
return & dev -> primary ;
91
92
case DRM_MINOR_RENDER :
92
93
return & dev -> render ;
94
+ case DRM_MINOR_ACCEL :
95
+ return & dev -> accel ;
93
96
default :
94
97
BUG ();
95
98
}
@@ -104,9 +107,13 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data)
104
107
105
108
put_device (minor -> kdev );
106
109
107
- spin_lock_irqsave (& drm_minor_lock , flags );
108
- idr_remove (& drm_minors_idr , minor -> index );
109
- spin_unlock_irqrestore (& drm_minor_lock , flags );
110
+ if (minor -> type == DRM_MINOR_ACCEL ) {
111
+ accel_minor_remove (minor -> index );
112
+ } else {
113
+ spin_lock_irqsave (& drm_minor_lock , flags );
114
+ idr_remove (& drm_minors_idr , minor -> index );
115
+ spin_unlock_irqrestore (& drm_minor_lock , flags );
116
+ }
110
117
}
111
118
112
119
static int drm_minor_alloc (struct drm_device * dev , unsigned int type )
@@ -123,13 +130,17 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
123
130
minor -> dev = dev ;
124
131
125
132
idr_preload (GFP_KERNEL );
126
- spin_lock_irqsave (& drm_minor_lock , flags );
127
- r = idr_alloc (& drm_minors_idr ,
128
- NULL ,
129
- 64 * type ,
130
- 64 * (type + 1 ),
131
- GFP_NOWAIT );
132
- spin_unlock_irqrestore (& drm_minor_lock , flags );
133
+ if (type == DRM_MINOR_ACCEL ) {
134
+ r = accel_minor_alloc ();
135
+ } else {
136
+ spin_lock_irqsave (& drm_minor_lock , flags );
137
+ r = idr_alloc (& drm_minors_idr ,
138
+ NULL ,
139
+ 64 * type ,
140
+ 64 * (type + 1 ),
141
+ GFP_NOWAIT );
142
+ spin_unlock_irqrestore (& drm_minor_lock , flags );
143
+ }
133
144
idr_preload_end ();
134
145
135
146
if (r < 0 )
@@ -161,20 +172,28 @@ static int drm_minor_register(struct drm_device *dev, unsigned int type)
161
172
if (!minor )
162
173
return 0 ;
163
174
164
- ret = drm_debugfs_init (minor , minor -> index , drm_debugfs_root );
165
- if (ret ) {
166
- DRM_ERROR ("DRM: Failed to initialize /sys/kernel/debug/dri.\n" );
167
- goto err_debugfs ;
175
+ if (minor -> type == DRM_MINOR_ACCEL ) {
176
+ accel_debugfs_init (minor , minor -> index );
177
+ } else {
178
+ ret = drm_debugfs_init (minor , minor -> index , drm_debugfs_root );
179
+ if (ret ) {
180
+ DRM_ERROR ("DRM: Failed to initialize /sys/kernel/debug/dri.\n" );
181
+ goto err_debugfs ;
182
+ }
168
183
}
169
184
170
185
ret = device_add (minor -> kdev );
171
186
if (ret )
172
187
goto err_debugfs ;
173
188
174
189
/* replace NULL with @minor so lookups will succeed from now on */
175
- spin_lock_irqsave (& drm_minor_lock , flags );
176
- idr_replace (& drm_minors_idr , minor , minor -> index );
177
- spin_unlock_irqrestore (& drm_minor_lock , flags );
190
+ if (minor -> type == DRM_MINOR_ACCEL ) {
191
+ accel_minor_replace (minor , minor -> index );
192
+ } else {
193
+ spin_lock_irqsave (& drm_minor_lock , flags );
194
+ idr_replace (& drm_minors_idr , minor , minor -> index );
195
+ spin_unlock_irqrestore (& drm_minor_lock , flags );
196
+ }
178
197
179
198
DRM_DEBUG ("new minor registered %d\n" , minor -> index );
180
199
return 0 ;
@@ -194,9 +213,13 @@ static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
194
213
return ;
195
214
196
215
/* replace @minor with NULL so lookups will fail from now on */
197
- spin_lock_irqsave (& drm_minor_lock , flags );
198
- idr_replace (& drm_minors_idr , NULL , minor -> index );
199
- spin_unlock_irqrestore (& drm_minor_lock , flags );
216
+ if (minor -> type == DRM_MINOR_ACCEL ) {
217
+ accel_minor_replace (NULL , minor -> index );
218
+ } else {
219
+ spin_lock_irqsave (& drm_minor_lock , flags );
220
+ idr_replace (& drm_minors_idr , NULL , minor -> index );
221
+ spin_unlock_irqrestore (& drm_minor_lock , flags );
222
+ }
200
223
201
224
device_del (minor -> kdev );
202
225
dev_set_drvdata (minor -> kdev , NULL ); /* safety belt */
@@ -603,6 +626,13 @@ static int drm_dev_init(struct drm_device *dev,
603
626
/* no per-device feature limits by default */
604
627
dev -> driver_features = ~0u ;
605
628
629
+ if (drm_core_check_feature (dev , DRIVER_COMPUTE_ACCEL ) &&
630
+ (drm_core_check_feature (dev , DRIVER_RENDER ) ||
631
+ drm_core_check_feature (dev , DRIVER_MODESET ))) {
632
+ DRM_ERROR ("DRM driver can't be both a compute acceleration and graphics driver\n" );
633
+ return - EINVAL ;
634
+ }
635
+
606
636
drm_legacy_init_members (dev );
607
637
INIT_LIST_HEAD (& dev -> filelist );
608
638
INIT_LIST_HEAD (& dev -> filelist_internal );
@@ -628,15 +658,21 @@ static int drm_dev_init(struct drm_device *dev,
628
658
629
659
dev -> anon_inode = inode ;
630
660
631
- if (drm_core_check_feature (dev , DRIVER_RENDER )) {
632
- ret = drm_minor_alloc (dev , DRM_MINOR_RENDER );
661
+ if (drm_core_check_feature (dev , DRIVER_COMPUTE_ACCEL )) {
662
+ ret = drm_minor_alloc (dev , DRM_MINOR_ACCEL );
633
663
if (ret )
634
664
goto err ;
635
- }
665
+ } else {
666
+ if (drm_core_check_feature (dev , DRIVER_RENDER )) {
667
+ ret = drm_minor_alloc (dev , DRM_MINOR_RENDER );
668
+ if (ret )
669
+ goto err ;
670
+ }
636
671
637
- ret = drm_minor_alloc (dev , DRM_MINOR_PRIMARY );
638
- if (ret )
639
- goto err ;
672
+ ret = drm_minor_alloc (dev , DRM_MINOR_PRIMARY );
673
+ if (ret )
674
+ goto err ;
675
+ }
640
676
641
677
ret = drm_legacy_create_map_hash (dev );
642
678
if (ret )
@@ -883,6 +919,10 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
883
919
if (ret )
884
920
goto err_minors ;
885
921
922
+ ret = drm_minor_register (dev , DRM_MINOR_ACCEL );
923
+ if (ret )
924
+ goto err_minors ;
925
+
886
926
ret = create_compat_control_link (dev );
887
927
if (ret )
888
928
goto err_minors ;
@@ -902,12 +942,13 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
902
942
driver -> name , driver -> major , driver -> minor ,
903
943
driver -> patchlevel , driver -> date ,
904
944
dev -> dev ? dev_name (dev -> dev ) : "virtual device" ,
905
- dev -> primary -> index );
945
+ dev -> primary ? dev -> primary -> index : dev -> accel -> index );
906
946
907
947
goto out_unlock ;
908
948
909
949
err_minors :
910
950
remove_compat_control_link (dev );
951
+ drm_minor_unregister (dev , DRM_MINOR_ACCEL );
911
952
drm_minor_unregister (dev , DRM_MINOR_PRIMARY );
912
953
drm_minor_unregister (dev , DRM_MINOR_RENDER );
913
954
out_unlock :
@@ -950,6 +991,7 @@ void drm_dev_unregister(struct drm_device *dev)
950
991
drm_legacy_rmmaps (dev );
951
992
952
993
remove_compat_control_link (dev );
994
+ drm_minor_unregister (dev , DRM_MINOR_ACCEL );
953
995
drm_minor_unregister (dev , DRM_MINOR_PRIMARY );
954
996
drm_minor_unregister (dev , DRM_MINOR_RENDER );
955
997
}
@@ -1034,6 +1076,7 @@ static const struct file_operations drm_stub_fops = {
1034
1076
static void drm_core_exit (void )
1035
1077
{
1036
1078
drm_privacy_screen_lookup_exit ();
1079
+ accel_core_exit ();
1037
1080
unregister_chrdev (DRM_MAJOR , "drm" );
1038
1081
debugfs_remove (drm_debugfs_root );
1039
1082
drm_sysfs_destroy ();
@@ -1061,6 +1104,10 @@ static int __init drm_core_init(void)
1061
1104
if (ret < 0 )
1062
1105
goto error ;
1063
1106
1107
+ ret = accel_core_init ();
1108
+ if (ret < 0 )
1109
+ goto error ;
1110
+
1064
1111
drm_privacy_screen_lookup_init ();
1065
1112
1066
1113
drm_core_init_complete = true;
0 commit comments