2013-09-09 04:02:56 +04:00
/*
* Copyright ( C ) 2015 Red Hat , Inc .
* All Rights Reserved .
*
* Permission is hereby granted , free of charge , to any person obtaining
* a copy of this software and associated documentation files ( the
* " Software " ) , to deal in the Software without restriction , including
* without limitation the rights to use , copy , modify , merge , publish ,
* distribute , sublicense , and / or sell copies of the Software , and to
* permit persons to whom the Software is furnished to do so , subject to
* the following conditions :
*
* The above copyright notice and this permission notice ( including the
* next paragraph ) shall be included in all copies or substantial
* portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND ,
* EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT .
* IN NO EVENT SHALL THE COPYRIGHT OWNER ( S ) AND / OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION
* OF CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
*/
# include <drm/drmP.h>
# include "virtgpu_drv.h"
2016-10-25 15:00:45 +03:00
static const char * virtio_get_driver_name ( struct dma_fence * f )
2013-09-09 04:02:56 +04:00
{
return " virtio_gpu " ;
}
2016-10-25 15:00:45 +03:00
static const char * virtio_get_timeline_name ( struct dma_fence * f )
2013-09-09 04:02:56 +04:00
{
return " controlq " ;
}
2016-10-25 15:00:45 +03:00
static bool virtio_signaled ( struct dma_fence * f )
2013-09-09 04:02:56 +04:00
{
struct virtio_gpu_fence * fence = to_virtio_fence ( f ) ;
if ( atomic64_read ( & fence - > drv - > last_seq ) > = fence - > seq )
return true ;
return false ;
}
2016-10-25 15:00:45 +03:00
static void virtio_fence_value_str ( struct dma_fence * f , char * str , int size )
2013-09-09 04:02:56 +04:00
{
struct virtio_gpu_fence * fence = to_virtio_fence ( f ) ;
snprintf ( str , size , " %llu " , fence - > seq ) ;
}
2016-10-25 15:00:45 +03:00
static void virtio_timeline_value_str ( struct dma_fence * f , char * str , int size )
2013-09-09 04:02:56 +04:00
{
struct virtio_gpu_fence * fence = to_virtio_fence ( f ) ;
drm/virtio: use %llu format string form atomic64_t
The virtgpu driver prints the last_seq variable using the %ld or
%lu format string, which does not work correctly on all architectures
and causes this compiler warning on ARM:
drivers/gpu/drm/virtio/virtgpu_fence.c: In function 'virtio_timeline_value_str':
drivers/gpu/drm/virtio/virtgpu_fence.c:64:22: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'long long int' [-Wformat=]
snprintf(str, size, "%lu", atomic64_read(&fence->drv->last_seq));
^
drivers/gpu/drm/virtio/virtgpu_debugfs.c: In function 'virtio_gpu_debugfs_irq_info':
drivers/gpu/drm/virtio/virtgpu_debugfs.c:37:16: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'long long int' [-Wformat=]
seq_printf(m, "fence %ld %lld\n",
^
In order to avoid the warnings, this changes the format strings to %llu
and adds a cast to u64, which makes it work the same way everywhere.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2015-10-07 13:41:21 +03:00
snprintf ( str , size , " %llu " , ( u64 ) atomic64_read ( & fence - > drv - > last_seq ) ) ;
2013-09-09 04:02:56 +04:00
}
2016-10-25 15:00:45 +03:00
static const struct dma_fence_ops virtio_fence_ops = {
2013-09-09 04:02:56 +04:00
. get_driver_name = virtio_get_driver_name ,
. get_timeline_name = virtio_get_timeline_name ,
. signaled = virtio_signaled ,
. fence_value_str = virtio_fence_value_str ,
. timeline_value_str = virtio_timeline_value_str ,
} ;
2018-11-12 19:51:54 +03:00
struct virtio_gpu_fence * virtio_gpu_fence_alloc ( struct virtio_gpu_device * vgdev )
{
struct virtio_gpu_fence_driver * drv = & vgdev - > fence_drv ;
struct virtio_gpu_fence * fence = kzalloc ( sizeof ( struct virtio_gpu_fence ) ,
GFP_ATOMIC ) ;
if ( ! fence )
return fence ;
fence - > drv = drv ;
dma_fence_init ( & fence - > f , & virtio_fence_ops , & drv - > lock , drv - > context , 0 ) ;
return fence ;
}
void virtio_gpu_fence_cleanup ( struct virtio_gpu_fence * fence )
{
if ( ! fence )
return ;
dma_fence_put ( & fence - > f ) ;
}
2013-09-09 04:02:56 +04:00
int virtio_gpu_fence_emit ( struct virtio_gpu_device * vgdev ,
struct virtio_gpu_ctrl_hdr * cmd_hdr ,
2018-11-28 18:10:20 +03:00
struct virtio_gpu_fence * fence )
2013-09-09 04:02:56 +04:00
{
struct virtio_gpu_fence_driver * drv = & vgdev - > fence_drv ;
unsigned long irq_flags ;
spin_lock_irqsave ( & drv - > lock , irq_flags ) ;
2018-11-28 18:10:20 +03:00
fence - > seq = + + drv - > sync_seq ;
dma_fence_get ( & fence - > f ) ;
list_add_tail ( & fence - > node , & drv - > fences ) ;
2013-09-09 04:02:56 +04:00
spin_unlock_irqrestore ( & drv - > lock , irq_flags ) ;
cmd_hdr - > flags | = cpu_to_le32 ( VIRTIO_GPU_FLAG_FENCE ) ;
2018-11-28 18:10:20 +03:00
cmd_hdr - > fence_id = cpu_to_le64 ( fence - > seq ) ;
2013-09-09 04:02:56 +04:00
return 0 ;
}
void virtio_gpu_fence_event_process ( struct virtio_gpu_device * vgdev ,
u64 last_seq )
{
struct virtio_gpu_fence_driver * drv = & vgdev - > fence_drv ;
struct virtio_gpu_fence * fence , * tmp ;
unsigned long irq_flags ;
spin_lock_irqsave ( & drv - > lock , irq_flags ) ;
atomic64_set ( & vgdev - > fence_drv . last_seq , last_seq ) ;
list_for_each_entry_safe ( fence , tmp , & drv - > fences , node ) {
if ( last_seq < fence - > seq )
continue ;
2016-10-25 15:00:45 +03:00
dma_fence_signal_locked ( & fence - > f ) ;
2013-09-09 04:02:56 +04:00
list_del ( & fence - > node ) ;
2016-10-25 15:00:45 +03:00
dma_fence_put ( & fence - > f ) ;
2013-09-09 04:02:56 +04:00
}
spin_unlock_irqrestore ( & drv - > lock , irq_flags ) ;
}