3333
3434void vmw_du_cleanup (struct vmw_display_unit * du )
3535{
36- if (du -> cursor_surface )
37- vmw_surface_unreference (& du -> cursor_surface );
38- if (du -> cursor_dmabuf )
39- vmw_dmabuf_unreference (& du -> cursor_dmabuf );
36+ drm_plane_cleanup (& du -> primary );
37+ drm_plane_cleanup (& du -> cursor );
38+
4039 drm_connector_unregister (& du -> connector );
4140 drm_crtc_cleanup (& du -> crtc );
4241 drm_encoder_cleanup (& du -> encoder );
@@ -47,9 +46,9 @@ void vmw_du_cleanup(struct vmw_display_unit *du)
4746 * Display Unit Cursor functions
4847 */
4948
50- int vmw_cursor_update_image (struct vmw_private * dev_priv ,
51- u32 * image , u32 width , u32 height ,
52- u32 hotspotX , u32 hotspotY )
49+ static int vmw_cursor_update_image (struct vmw_private * dev_priv ,
50+ u32 * image , u32 width , u32 height ,
51+ u32 hotspotX , u32 hotspotY )
5352{
5453 struct {
5554 u32 cmd ;
@@ -83,10 +82,10 @@ int vmw_cursor_update_image(struct vmw_private *dev_priv,
8382 return 0 ;
8483}
8584
86- int vmw_cursor_update_dmabuf (struct vmw_private * dev_priv ,
87- struct vmw_dma_buffer * dmabuf ,
88- u32 width , u32 height ,
89- u32 hotspotX , u32 hotspotY )
85+ static int vmw_cursor_update_dmabuf (struct vmw_private * dev_priv ,
86+ struct vmw_dma_buffer * dmabuf ,
87+ u32 width , u32 height ,
88+ u32 hotspotX , u32 hotspotY )
9089{
9190 struct ttm_bo_kmap_obj map ;
9291 unsigned long kmap_offset ;
@@ -120,145 +119,22 @@ int vmw_cursor_update_dmabuf(struct vmw_private *dev_priv,
120119}
121120
122121
123- void vmw_cursor_update_position (struct vmw_private * dev_priv ,
124- bool show , int x , int y )
122+ static void vmw_cursor_update_position (struct vmw_private * dev_priv ,
123+ bool show , int x , int y )
125124{
126125 u32 * fifo_mem = dev_priv -> mmio_virt ;
127126 uint32_t count ;
128127
128+ spin_lock (& dev_priv -> cursor_lock );
129129 vmw_mmio_write (show ? 1 : 0 , fifo_mem + SVGA_FIFO_CURSOR_ON );
130130 vmw_mmio_write (x , fifo_mem + SVGA_FIFO_CURSOR_X );
131131 vmw_mmio_write (y , fifo_mem + SVGA_FIFO_CURSOR_Y );
132132 count = vmw_mmio_read (fifo_mem + SVGA_FIFO_CURSOR_COUNT );
133133 vmw_mmio_write (++ count , fifo_mem + SVGA_FIFO_CURSOR_COUNT );
134+ spin_unlock (& dev_priv -> cursor_lock );
134135}
135136
136137
137- /*
138- * vmw_du_crtc_cursor_set2 - Driver cursor_set2 callback.
139- */
140- int vmw_du_crtc_cursor_set2 (struct drm_crtc * crtc , struct drm_file * file_priv ,
141- uint32_t handle , uint32_t width , uint32_t height ,
142- int32_t hot_x , int32_t hot_y )
143- {
144- struct vmw_private * dev_priv = vmw_priv (crtc -> dev );
145- struct vmw_display_unit * du = vmw_crtc_to_du (crtc );
146- struct vmw_surface * surface = NULL ;
147- struct vmw_dma_buffer * dmabuf = NULL ;
148- s32 hotspot_x , hotspot_y ;
149- int ret ;
150-
151- /*
152- * FIXME: Unclear whether there's any global state touched by the
153- * cursor_set function, especially vmw_cursor_update_position looks
154- * suspicious. For now take the easy route and reacquire all locks. We
155- * can do this since the caller in the drm core doesn't check anything
156- * which is protected by any looks.
157- */
158- drm_modeset_unlock_crtc (crtc );
159- drm_modeset_lock_all (dev_priv -> dev );
160- hotspot_x = hot_x + du -> hotspot_x ;
161- hotspot_y = hot_y + du -> hotspot_y ;
162-
163- /* A lot of the code assumes this */
164- if (handle && (width != 64 || height != 64 )) {
165- ret = - EINVAL ;
166- goto out ;
167- }
168-
169- if (handle ) {
170- struct ttm_object_file * tfile = vmw_fpriv (file_priv )-> tfile ;
171-
172- ret = vmw_user_lookup_handle (dev_priv , tfile ,
173- handle , & surface , & dmabuf );
174- if (ret ) {
175- DRM_ERROR ("failed to find surface or dmabuf: %i\n" , ret );
176- ret = - EINVAL ;
177- goto out ;
178- }
179- }
180-
181- /* need to do this before taking down old image */
182- if (surface && !surface -> snooper .image ) {
183- DRM_ERROR ("surface not suitable for cursor\n" );
184- vmw_surface_unreference (& surface );
185- ret = - EINVAL ;
186- goto out ;
187- }
188-
189- /* takedown old cursor */
190- if (du -> cursor_surface ) {
191- vmw_surface_unreference (& du -> cursor_surface );
192- }
193- if (du -> cursor_dmabuf )
194- vmw_dmabuf_unreference (& du -> cursor_dmabuf );
195-
196- /* setup new image */
197- ret = 0 ;
198- if (surface ) {
199- /* vmw_user_surface_lookup takes one reference */
200- du -> cursor_surface = surface ;
201-
202- du -> cursor_age = du -> cursor_surface -> snooper .age ;
203- ret = vmw_cursor_update_image (dev_priv , surface -> snooper .image ,
204- 64 , 64 , hotspot_x , hotspot_y );
205- } else if (dmabuf ) {
206- /* vmw_user_surface_lookup takes one reference */
207- du -> cursor_dmabuf = dmabuf ;
208-
209- ret = vmw_cursor_update_dmabuf (dev_priv , dmabuf , width , height ,
210- hotspot_x , hotspot_y );
211- } else {
212- vmw_cursor_update_position (dev_priv , false, 0 , 0 );
213- goto out ;
214- }
215-
216- if (!ret ) {
217- vmw_cursor_update_position (dev_priv , true,
218- du -> cursor_x + hotspot_x ,
219- du -> cursor_y + hotspot_y );
220- du -> core_hotspot_x = hot_x ;
221- du -> core_hotspot_y = hot_y ;
222- }
223-
224- out :
225- drm_modeset_unlock_all (dev_priv -> dev );
226- drm_modeset_lock_crtc (crtc , crtc -> cursor );
227-
228- return ret ;
229- }
230-
231- int vmw_du_crtc_cursor_move (struct drm_crtc * crtc , int x , int y )
232- {
233- struct vmw_private * dev_priv = vmw_priv (crtc -> dev );
234- struct vmw_display_unit * du = vmw_crtc_to_du (crtc );
235- bool shown = du -> cursor_surface || du -> cursor_dmabuf ? true : false;
236-
237- du -> cursor_x = x + du -> set_gui_x ;
238- du -> cursor_y = y + du -> set_gui_y ;
239-
240- /*
241- * FIXME: Unclear whether there's any global state touched by the
242- * cursor_set function, especially vmw_cursor_update_position looks
243- * suspicious. For now take the easy route and reacquire all locks. We
244- * can do this since the caller in the drm core doesn't check anything
245- * which is protected by any looks.
246- */
247- drm_modeset_unlock_crtc (crtc );
248- drm_modeset_lock_all (dev_priv -> dev );
249-
250- vmw_cursor_update_position (dev_priv , shown ,
251- du -> cursor_x + du -> hotspot_x +
252- du -> core_hotspot_x ,
253- du -> cursor_y + du -> hotspot_y +
254- du -> core_hotspot_y );
255-
256- drm_modeset_unlock_all (dev_priv -> dev );
257- drm_modeset_lock_crtc (crtc , crtc -> cursor );
258-
259- return 0 ;
260- }
261-
262138void vmw_kms_cursor_snoop (struct vmw_surface * srf ,
263139 struct ttm_object_file * tfile ,
264140 struct ttm_buffer_object * bo ,
@@ -393,6 +269,125 @@ void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
393269 mutex_unlock (& dev -> mode_config .mutex );
394270}
395271
272+
273+
274+ /**
275+ * vmw_du_cursor_plane_update() - Update cursor image and location
276+ *
277+ * @plane: plane object to update
278+ * @crtc: owning CRTC of @plane
279+ * @fb: framebuffer to flip onto plane
280+ * @crtc_x: x offset of plane on crtc
281+ * @crtc_y: y offset of plane on crtc
282+ * @crtc_w: width of plane rectangle on crtc
283+ * @crtc_h: height of plane rectangle on crtc
284+ * @src_x: Not used
285+ * @src_y: Not used
286+ * @src_w: Not used
287+ * @src_h: Not used
288+ *
289+ *
290+ * RETURNS:
291+ * Zero on success, error code on failure
292+ */
293+ int vmw_du_cursor_plane_update (struct drm_plane * plane ,
294+ struct drm_crtc * crtc ,
295+ struct drm_framebuffer * fb ,
296+ int crtc_x , int crtc_y ,
297+ unsigned int crtc_w ,
298+ unsigned int crtc_h ,
299+ uint32_t src_x , uint32_t src_y ,
300+ uint32_t src_w , uint32_t src_h )
301+ {
302+ struct vmw_private * dev_priv = vmw_priv (crtc -> dev );
303+ struct vmw_display_unit * du = vmw_crtc_to_du (crtc );
304+ struct vmw_surface * surface = NULL ;
305+ struct vmw_dma_buffer * dmabuf = NULL ;
306+ s32 hotspot_x , hotspot_y ;
307+ int ret ;
308+
309+ hotspot_x = du -> hotspot_x + fb -> hot_x ;
310+ hotspot_y = du -> hotspot_y + fb -> hot_y ;
311+
312+ /* A lot of the code assumes this */
313+ if (crtc_w != 64 || crtc_h != 64 ) {
314+ ret = - EINVAL ;
315+ goto out ;
316+ }
317+
318+ if (vmw_framebuffer_to_vfb (fb )-> dmabuf )
319+ dmabuf = vmw_framebuffer_to_vfbd (fb )-> buffer ;
320+ else
321+ surface = vmw_framebuffer_to_vfbs (fb )-> surface ;
322+
323+ if (surface && !surface -> snooper .image ) {
324+ DRM_ERROR ("surface not suitable for cursor\n" );
325+ ret = - EINVAL ;
326+ goto out ;
327+ }
328+
329+ /* setup new image */
330+ ret = 0 ;
331+ if (surface ) {
332+ /* vmw_user_surface_lookup takes one reference */
333+ du -> cursor_surface = surface ;
334+
335+ du -> cursor_age = du -> cursor_surface -> snooper .age ;
336+
337+ ret = vmw_cursor_update_image (dev_priv , surface -> snooper .image ,
338+ 64 , 64 , hotspot_x , hotspot_y );
339+ } else if (dmabuf ) {
340+ /* vmw_user_surface_lookup takes one reference */
341+ du -> cursor_dmabuf = dmabuf ;
342+
343+ ret = vmw_cursor_update_dmabuf (dev_priv , dmabuf , crtc_w , crtc_h ,
344+ hotspot_x , hotspot_y );
345+ } else {
346+ vmw_cursor_update_position (dev_priv , false, 0 , 0 );
347+ goto out ;
348+ }
349+
350+ if (!ret ) {
351+ du -> cursor_x = crtc_x + du -> set_gui_x ;
352+ du -> cursor_y = crtc_y + du -> set_gui_y ;
353+
354+ vmw_cursor_update_position (dev_priv , true,
355+ du -> cursor_x + hotspot_x ,
356+ du -> cursor_y + hotspot_y );
357+ }
358+
359+ out :
360+ return ret ;
361+ }
362+
363+
364+ int vmw_du_cursor_plane_disable (struct drm_plane * plane )
365+ {
366+ if (plane -> fb ) {
367+ drm_framebuffer_unreference (plane -> fb );
368+ plane -> fb = NULL ;
369+ }
370+
371+ return - EINVAL ;
372+ }
373+
374+
375+ void vmw_du_cursor_plane_destroy (struct drm_plane * plane )
376+ {
377+ vmw_cursor_update_position (plane -> dev -> dev_private , false, 0 , 0 );
378+
379+ drm_plane_cleanup (plane );
380+ }
381+
382+
383+ void vmw_du_primary_plane_destroy (struct drm_plane * plane )
384+ {
385+ drm_plane_cleanup (plane );
386+
387+ /* Planes are static in our case so we don't free it */
388+ }
389+
390+
396391/*
397392 * Generic framebuffer code
398393 */
0 commit comments