From ae9658c5c01f8c146c8d3e5ba8a2b11e880a1db4 Mon Sep 17 00:00:00 2001 From: jsg Date: Sun, 5 Feb 2017 05:38:00 +0000 Subject: [PATCH] Import libdrm 2.4.75 --- lib/libdrm/etnaviv/etnaviv-symbol-check | 3 + lib/libdrm/etnaviv/etnaviv_bo.c | 2 +- lib/libdrm/etnaviv/etnaviv_device.c | 23 ++ lib/libdrm/etnaviv/etnaviv_drmif.h | 3 + lib/libdrm/etnaviv/etnaviv_pipe.c | 9 +- lib/libdrm/etnaviv/etnaviv_priv.h | 8 +- lib/libdrm/freedreno/freedreno-symbol-check | 1 + lib/libdrm/freedreno/freedreno_pipe.c | 4 + lib/libdrm/freedreno/freedreno_priv.h | 1 + lib/libdrm/freedreno/freedreno_ringbuffer.c | 9 + lib/libdrm/freedreno/freedreno_ringbuffer.h | 6 +- lib/libdrm/freedreno/kgsl/kgsl_pipe.c | 5 + lib/libdrm/freedreno/msm/msm_ringbuffer.c | 27 +- lib/libdrm/include/drm/README | 2 +- lib/libdrm/include/drm/vc4_drm.h | 2 + lib/libdrm/intel/intel-symbol-check | 5 + lib/libdrm/libkms/Makefile.am | 4 - lib/libdrm/libkms/exynos.c | 3 +- lib/libdrm/tests/Makefile.am | 46 +--- lib/libdrm/tests/amdgpu/amdgpu_test.c | 257 +++++++++++++++++--- lib/libdrm/tests/amdgpu/amdgpu_test.h | 3 + lib/libdrm/tests/amdgpu/basic_tests.c | 7 +- lib/libdrm/tests/amdgpu/bo_tests.c | 13 +- lib/libdrm/tests/amdgpu/cs_tests.c | 8 +- lib/libdrm/tests/amdgpu/vce_tests.c | 8 +- lib/libdrm/tests/drmdevice.c | 60 ++++- lib/libdrm/tests/exynos/Makefile.am | 4 +- lib/libdrm/tests/kms/kms-universal-planes.c | 2 +- lib/libdrm/tests/modetest/Makefile.am | 4 +- lib/libdrm/tests/modetest/modetest.c | 28 ++- lib/libdrm/tests/nouveau/Makefile.am | 8 +- lib/libdrm/tests/util/kms.c | 1 + 32 files changed, 450 insertions(+), 116 deletions(-) diff --git a/lib/libdrm/etnaviv/etnaviv-symbol-check b/lib/libdrm/etnaviv/etnaviv-symbol-check index 77c94c6ed..22afd1683 100755 --- a/lib/libdrm/etnaviv/etnaviv-symbol-check +++ b/lib/libdrm/etnaviv/etnaviv-symbol-check @@ -11,14 +11,17 @@ _end _fini _init etna_device_new +etna_device_new_dup etna_device_ref etna_device_del +etna_device_fd etna_gpu_new etna_gpu_del etna_gpu_get_param etna_pipe_new etna_pipe_del etna_pipe_wait +etna_pipe_wait_ns etna_bo_new etna_bo_from_handle etna_bo_from_name diff --git a/lib/libdrm/etnaviv/etnaviv_bo.c b/lib/libdrm/etnaviv/etnaviv_bo.c index 833f8bd40..4ad0434e7 100644 --- a/lib/libdrm/etnaviv/etnaviv_bo.c +++ b/lib/libdrm/etnaviv/etnaviv_bo.c @@ -330,7 +330,7 @@ int etna_bo_cpu_prep(struct etna_bo *bo, uint32_t op) .op = op, }; - get_abs_timeout(&req.timeout, 5000); + get_abs_timeout(&req.timeout, 5000000000); return drmCommandWrite(bo->dev->fd, DRM_ETNAVIV_GEM_CPU_PREP, &req, sizeof(req)); diff --git a/lib/libdrm/etnaviv/etnaviv_device.c b/lib/libdrm/etnaviv/etnaviv_device.c index f954ca4e6..3ce92030e 100644 --- a/lib/libdrm/etnaviv/etnaviv_device.c +++ b/lib/libdrm/etnaviv/etnaviv_device.c @@ -61,6 +61,21 @@ struct etna_device *etna_device_new(int fd) return dev; } +/* like etna_device_new() but creates it's own private dup() of the fd + * which is close()d when the device is finalized. */ +struct etna_device *etna_device_new_dup(int fd) +{ + int dup_fd = dup(fd); + struct etna_device *dev = etna_device_new(dup_fd); + + if (dev) + dev->closefd = 1; + else + close(dup_fd); + + return dev; +} + struct etna_device *etna_device_ref(struct etna_device *dev) { atomic_inc(&dev->refcnt); @@ -74,6 +89,9 @@ static void etna_device_del_impl(struct etna_device *dev) drmHashDestroy(dev->handle_table); drmHashDestroy(dev->name_table); + if (dev->closefd) + close(dev->fd); + free(dev); } @@ -94,3 +112,8 @@ void etna_device_del(struct etna_device *dev) etna_device_del_impl(dev); pthread_mutex_unlock(&table_lock); } + +int etna_device_fd(struct etna_device *dev) +{ + return dev->fd; +} diff --git a/lib/libdrm/etnaviv/etnaviv_drmif.h b/lib/libdrm/etnaviv/etnaviv_drmif.h index 979b16a9a..8119baad9 100644 --- a/lib/libdrm/etnaviv/etnaviv_drmif.h +++ b/lib/libdrm/etnaviv/etnaviv_drmif.h @@ -84,8 +84,10 @@ enum etna_param_id { */ struct etna_device *etna_device_new(int fd); +struct etna_device *etna_device_new_dup(int fd); struct etna_device *etna_device_ref(struct etna_device *dev); void etna_device_del(struct etna_device *dev); +int etna_device_fd(struct etna_device *dev); /* gpu functions: */ @@ -102,6 +104,7 @@ int etna_gpu_get_param(struct etna_gpu *gpu, enum etna_param_id param, struct etna_pipe *etna_pipe_new(struct etna_gpu *gpu, enum etna_pipe_id id); void etna_pipe_del(struct etna_pipe *pipe); int etna_pipe_wait(struct etna_pipe *pipe, uint32_t timestamp, uint32_t ms); +int etna_pipe_wait_ns(struct etna_pipe *pipe, uint32_t timestamp, uint64_t ns); /* buffer-object functions: diff --git a/lib/libdrm/etnaviv/etnaviv_pipe.c b/lib/libdrm/etnaviv/etnaviv_pipe.c index 402b71d63..94c5d3778 100644 --- a/lib/libdrm/etnaviv/etnaviv_pipe.c +++ b/lib/libdrm/etnaviv/etnaviv_pipe.c @@ -31,6 +31,11 @@ #include "etnaviv_priv.h" int etna_pipe_wait(struct etna_pipe *pipe, uint32_t timestamp, uint32_t ms) +{ + return etna_pipe_wait_ns(pipe, timestamp, ms * 1000000); +} + +int etna_pipe_wait_ns(struct etna_pipe *pipe, uint32_t timestamp, uint64_t ns) { struct etna_device *dev = pipe->gpu->dev; int ret; @@ -40,10 +45,10 @@ int etna_pipe_wait(struct etna_pipe *pipe, uint32_t timestamp, uint32_t ms) .fence = timestamp, }; - if (ms == 0) + if (ns == 0) req.flags |= ETNA_WAIT_NONBLOCK; - get_abs_timeout(&req.timeout, ms); + get_abs_timeout(&req.timeout, ns); ret = drmCommandWrite(dev->fd, DRM_ETNAVIV_WAIT_FENCE, &req, sizeof(req)); if (ret) { diff --git a/lib/libdrm/etnaviv/etnaviv_priv.h b/lib/libdrm/etnaviv/etnaviv_priv.h index 6bb0c8dcb..feaa5ad99 100644 --- a/lib/libdrm/etnaviv/etnaviv_priv.h +++ b/lib/libdrm/etnaviv/etnaviv_priv.h @@ -93,6 +93,8 @@ struct etna_device { void *handle_table, *name_table; struct etna_bo_cache bo_cache; + + int closefd; /* call close(fd) upon destruction */ }; drm_private void etna_bo_cache_init(struct etna_bo_cache *cache); @@ -187,13 +189,13 @@ struct etna_cmd_stream_priv { #define VOID2U64(x) ((uint64_t)(unsigned long)(x)) -static inline void get_abs_timeout(struct drm_etnaviv_timespec *tv, uint32_t ms) +static inline void get_abs_timeout(struct drm_etnaviv_timespec *tv, uint64_t ns) { struct timespec t; - uint32_t s = ms / 1000; + uint32_t s = ns / 1000000000; clock_gettime(CLOCK_MONOTONIC, &t); tv->tv_sec = t.tv_sec + s; - tv->tv_nsec = t.tv_nsec + ((ms - (s * 1000)) * 1000000); + tv->tv_nsec = t.tv_nsec + ns - (s * 1000000000); } #endif /* ETNAVIV_PRIV_H_ */ diff --git a/lib/libdrm/freedreno/freedreno-symbol-check b/lib/libdrm/freedreno/freedreno-symbol-check index ad367fc34..42f2c4395 100755 --- a/lib/libdrm/freedreno/freedreno-symbol-check +++ b/lib/libdrm/freedreno/freedreno-symbol-check @@ -43,6 +43,7 @@ fd_ringbuffer_flush fd_ringbuffer_grow fd_ringbuffer_new fd_ringbuffer_reloc +fd_ringbuffer_reloc2 fd_ringbuffer_reset fd_ringbuffer_set_parent fd_ringbuffer_timestamp diff --git a/lib/libdrm/freedreno/freedreno_pipe.c b/lib/libdrm/freedreno/freedreno_pipe.c index 4a756d702..3f8c8342c 100644 --- a/lib/libdrm/freedreno/freedreno_pipe.c +++ b/lib/libdrm/freedreno/freedreno_pipe.c @@ -37,6 +37,7 @@ struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) { struct fd_pipe *pipe = NULL; + uint64_t val; if (id > FD_PIPE_MAX) { ERROR_MSG("invalid pipe id: %d", id); @@ -52,6 +53,9 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) pipe->dev = dev; pipe->id = id; + fd_pipe_get_param(pipe, FD_GPU_ID, &val); + pipe->gpu_id = val; + return pipe; fail: if (pipe) diff --git a/lib/libdrm/freedreno/freedreno_priv.h b/lib/libdrm/freedreno/freedreno_priv.h index 86da83b94..32170391a 100644 --- a/lib/libdrm/freedreno/freedreno_priv.h +++ b/lib/libdrm/freedreno/freedreno_priv.h @@ -123,6 +123,7 @@ struct fd_pipe_funcs { struct fd_pipe { struct fd_device *dev; enum fd_pipe_id id; + uint32_t gpu_id; const struct fd_pipe_funcs *funcs; }; diff --git a/lib/libdrm/freedreno/freedreno_ringbuffer.c b/lib/libdrm/freedreno/freedreno_ringbuffer.c index c132145af..7310f1fd4 100644 --- a/lib/libdrm/freedreno/freedreno_ringbuffer.c +++ b/lib/libdrm/freedreno/freedreno_ringbuffer.c @@ -114,6 +114,13 @@ uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring) void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, const struct fd_reloc *reloc) +{ + assert(ring->pipe->gpu_id < 500); + ring->funcs->emit_reloc(ring, reloc); +} + +void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring, + const struct fd_reloc *reloc) { ring->funcs->emit_reloc(ring, reloc); } @@ -123,6 +130,8 @@ void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, { uint32_t submit_offset, size; + /* This function is deprecated and not supported on 64b devices: */ + assert(ring->pipe->gpu_id < 500); assert(target->ring == end->ring); submit_offset = offset_bytes(target->cur, target->ring->start); diff --git a/lib/libdrm/freedreno/freedreno_ringbuffer.h b/lib/libdrm/freedreno/freedreno_ringbuffer.h index 108d5a6de..c501fbadb 100644 --- a/lib/libdrm/freedreno/freedreno_ringbuffer.h +++ b/lib/libdrm/freedreno/freedreno_ringbuffer.h @@ -78,9 +78,13 @@ struct fd_reloc { uint32_t offset; uint32_t or; int32_t shift; + uint32_t orhi; /* used for a5xx+ */ }; -void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, const struct fd_reloc *reloc); +/* NOTE: relocs are 2 dwords on a5xx+ */ + +void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring, const struct fd_reloc *reloc); +will_be_deprecated void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, const struct fd_reloc *reloc); will_be_deprecated void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, struct fd_ringmarker *target, struct fd_ringmarker *end); uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring); diff --git a/lib/libdrm/freedreno/kgsl/kgsl_pipe.c b/lib/libdrm/freedreno/kgsl/kgsl_pipe.c index 3546718db..8a39eb49e 100644 --- a/lib/libdrm/freedreno/kgsl/kgsl_pipe.c +++ b/lib/libdrm/freedreno/kgsl/kgsl_pipe.c @@ -255,6 +255,11 @@ drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, GETPROP(fd, VERSION, kgsl_pipe->version); GETPROP(fd, DEVICE_INFO, kgsl_pipe->devinfo); + if (kgsl_pipe->devinfo.gpu_id >= 500) { + ERROR_MSG("64b unsupported with kgsl"); + goto fail; + } + INFO_MSG("Pipe Info:"); INFO_MSG(" Device: %s", paths[id]); INFO_MSG(" Chip-id: %d.%d.%d.%d", diff --git a/lib/libdrm/freedreno/msm/msm_ringbuffer.c b/lib/libdrm/freedreno/msm/msm_ringbuffer.c index 5117df1a9..17194f4cc 100644 --- a/lib/libdrm/freedreno/msm/msm_ringbuffer.c +++ b/lib/libdrm/freedreno/msm/msm_ringbuffer.c @@ -487,11 +487,32 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring, reloc->submit_offset = offset_bytes(ring->cur, ring->start); addr = msm_bo->presumed; - if (r->shift < 0) - addr >>= -r->shift; + if (reloc->shift < 0) + addr >>= -reloc->shift; else - addr <<= r->shift; + addr <<= reloc->shift; (*ring->cur++) = addr | r->or; + + if (ring->pipe->gpu_id >= 500) { + struct drm_msm_gem_submit_reloc *reloc_hi; + + idx = APPEND(cmd, relocs); + + reloc_hi = &cmd->relocs[idx]; + + reloc_hi->reloc_idx = reloc->reloc_idx; + reloc_hi->reloc_offset = r->offset; + reloc_hi->or = r->orhi; + reloc_hi->shift = r->shift - 32; + reloc_hi->submit_offset = offset_bytes(ring->cur, ring->start); + + addr = msm_bo->presumed >> 32; + if (reloc_hi->shift < 0) + addr >>= -reloc_hi->shift; + else + addr <<= reloc_hi->shift; + (*ring->cur++) = addr | r->orhi; + } } static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, diff --git a/lib/libdrm/include/drm/README b/lib/libdrm/include/drm/README index c3292f312..a50b02c0a 100644 --- a/lib/libdrm/include/drm/README +++ b/lib/libdrm/include/drm/README @@ -89,7 +89,7 @@ Nearly all headers: Status: Trivial. Most UMS headers: - - Not using fixed size interers - compat ioctls are broken. + - Not using fixed size integers - compat ioctls are broken. Status: ? Promote to fixed size ints, which match the current (32bit) ones. diff --git a/lib/libdrm/include/drm/vc4_drm.h b/lib/libdrm/include/drm/vc4_drm.h index 919eecea7..319881d8e 100644 --- a/lib/libdrm/include/drm/vc4_drm.h +++ b/lib/libdrm/include/drm/vc4_drm.h @@ -286,6 +286,8 @@ struct drm_vc4_get_hang_state { #define DRM_VC4_PARAM_V3D_IDENT1 1 #define DRM_VC4_PARAM_V3D_IDENT2 2 #define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3 +#define DRM_VC4_PARAM_SUPPORTS_ETC1 4 +#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5 struct drm_vc4_get_param { __u32 param; diff --git a/lib/libdrm/intel/intel-symbol-check b/lib/libdrm/intel/intel-symbol-check index 4462533c2..2aa2d8192 100755 --- a/lib/libdrm/intel/intel-symbol-check +++ b/lib/libdrm/intel/intel-symbol-check @@ -50,6 +50,7 @@ drm_intel_bufmgr_fake_init drm_intel_bufmgr_fake_set_exec_callback drm_intel_bufmgr_fake_set_fence_callback drm_intel_bufmgr_fake_set_last_dispatch +drm_intel_bufmgr_gem_can_disable_implicit_sync drm_intel_bufmgr_gem_enable_fenced_relocs drm_intel_bufmgr_gem_enable_reuse drm_intel_bufmgr_gem_get_devid @@ -69,6 +70,9 @@ drm_intel_decode_set_output_file drm_intel_gem_bo_aub_dump_bmp drm_intel_gem_bo_clear_relocs drm_intel_gem_bo_context_exec +drm_intel_gem_bo_disable_implicit_sync +drm_intel_gem_bo_enable_implicit_sync +drm_intel_gem_bo_fence_exec drm_intel_gem_bo_get_reloc_count drm_intel_gem_bo_map__cpu drm_intel_gem_bo_map__gtt @@ -80,6 +84,7 @@ drm_intel_gem_bo_unmap_gtt drm_intel_gem_bo_wait drm_intel_gem_context_create drm_intel_gem_context_destroy +drm_intel_gem_context_get_id drm_intel_get_aperture_sizes drm_intel_get_eu_total drm_intel_get_min_eu_in_pool diff --git a/lib/libdrm/libkms/Makefile.am b/lib/libdrm/libkms/Makefile.am index 7c1debe26..461fc35b6 100644 --- a/lib/libdrm/libkms/Makefile.am +++ b/lib/libdrm/libkms/Makefile.am @@ -10,10 +10,6 @@ libkms_ladir = $(libdir) libkms_la_LDFLAGS = -version-number 1:0:0 -no-undefined libkms_la_LIBADD = ../libdrm.la -#if HAVE_LIBUDEV -#libkms_la_LIBADD += $(LIBUDEV_LIBS) -#endif - libkms_la_SOURCES = $(LIBKMS_FILES) if HAVE_VMWGFX diff --git a/lib/libdrm/libkms/exynos.c b/lib/libdrm/libkms/exynos.c index 5de2e5a95..0e97fb519 100644 --- a/lib/libdrm/libkms/exynos.c +++ b/lib/libdrm/libkms/exynos.c @@ -88,7 +88,8 @@ exynos_bo_create(struct kms_driver *kms, pitch = (pitch + 512 - 1) & ~(512 - 1); size = pitch * ((height + 4 - 1) & ~(4 - 1)); } else { - return -EINVAL; + ret = -EINVAL; + goto err_free; } memset(&arg, 0, sizeof(arg)); diff --git a/lib/libdrm/tests/Makefile.am b/lib/libdrm/tests/Makefile.am index 4a499e428..0355a9255 100644 --- a/lib/libdrm/tests/Makefile.am +++ b/lib/libdrm/tests/Makefile.am @@ -26,6 +26,10 @@ if HAVE_ETNAVIV SUBDIRS += etnaviv endif +if HAVE_NOUVEAU +SUBDIRS += nouveau +endif + AM_CFLAGS = \ $(WARN_CFLAGS)\ -I $(top_srcdir)/include/drm \ @@ -33,47 +37,11 @@ AM_CFLAGS = \ LDADD = $(top_builddir)/libdrm.la -check_PROGRAMS = \ - dristat \ - drmdevice \ - drmstat - -dristat_LDADD = -lm - -if HAVE_NOUVEAU -SUBDIRS += nouveau -endif - TESTS = \ drmsl \ hash \ random -if HAVE_LIBUDEV - -check_LTLIBRARIES = libdrmtest.la - -libdrmtest_la_SOURCES = \ - drmtest.c \ - drmtest.h - -LDADD += \ - libdrmtest.la \ - $(LIBUDEV_LIBS) - - -XFAIL_TESTS = \ - auth \ - lock - -TESTS += \ - openclose \ - getversion \ - getclient \ - getstats \ - setversion \ - updatedraw \ - name_from_fd -endif - -check_PROGRAMS += $(TESTS) +check_PROGRAMS = \ + $(TESTS) \ + drmdevice diff --git a/lib/libdrm/tests/amdgpu/amdgpu_test.c b/lib/libdrm/tests/amdgpu/amdgpu_test.c index 71f357c66..3fd6820a1 100644 --- a/lib/libdrm/tests/amdgpu/amdgpu_test.c +++ b/lib/libdrm/tests/amdgpu/amdgpu_test.c @@ -56,6 +56,9 @@ */ int drm_amdgpu[MAX_CARDS_SUPPORTED]; +/** Open render node to test */ +int open_render_node = 0; /* By default run most tests on primary node */ + /** The table of all known test suites to run */ static CU_SuiteInfo suites[] = { { @@ -108,12 +111,181 @@ static void display_test_suites(void) /** Help string for command line parameters */ -static const char usage[] = "Usage: %s [-hl] [<-s > [-t ]]\n" - "where:\n" - " l - Display all suites and their tests\n" - " h - Display this help\n"; +static const char usage[] = + "Usage: %s [-hlpr] [<-s > [-t ]] " + "[-b [-d ]]\n" + "where:\n" + " l - Display all suites and their tests\n" + " r - Run the tests on render node\n" + " b - Specify device's PCI bus id to run tests\n" + " d - Specify device's PCI device id to run tests (optional)\n" + " p - Display information of AMDGPU devices in system\n" + " h - Display this help\n"; /** Specified options strings for getopt */ -static const char options[] = "hls:t:"; +static const char options[] = "hlrps:t:b:d:"; + +/* Open AMD devices. + * Return the number of AMD device openned. + */ +static int amdgpu_open_devices(int open_render_node) +{ + drmDevicePtr devices[MAX_CARDS_SUPPORTED]; + int ret; + int i; + int drm_node; + int amd_index = 0; + int drm_count; + int fd; + drmVersionPtr version; + + drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED); + + if (drm_count < 0) { + fprintf(stderr, + "drmGetDevices2() returned an error %d\n", + drm_count); + return 0; + } + + for (i = 0; i < drm_count; i++) { + /* If this is not PCI device, skip*/ + if (devices[i]->bustype != DRM_BUS_PCI) + continue; + + /* If this is not AMD GPU vender ID, skip*/ + if (devices[i]->deviceinfo.pci->vendor_id != 0x1002) + continue; + + if (open_render_node) + drm_node = DRM_NODE_RENDER; + else + drm_node = DRM_NODE_PRIMARY; + + fd = -1; + if (devices[i]->available_nodes & 1 << drm_node) + fd = open( + devices[i]->nodes[drm_node], + O_RDWR | O_CLOEXEC); + + /* This node is not available. */ + if (fd < 0) continue; + + version = drmGetVersion(fd); + if (!version) { + fprintf(stderr, + "Warning: Cannot get version for %s." + "Error is %s\n", + devices[i]->nodes[drm_node], + strerror(errno)); + close(fd); + continue; + } + + if (strcmp(version->name, "amdgpu")) { + /* This is not AMDGPU driver, skip.*/ + drmFreeVersion(version); + close(fd); + continue; + } + + drmFreeVersion(version); + + drm_amdgpu[amd_index] = fd; + amd_index++; + } + + drmFreeDevices(devices, drm_count); + return amd_index; +} + +/* Close AMD devices. + */ +static void amdgpu_close_devices() +{ + int i; + for (i = 0; i < MAX_CARDS_SUPPORTED; i++) + if (drm_amdgpu[i] >=0) + close(drm_amdgpu[i]); +} + +/* Print AMD devices information */ +static void amdgpu_print_devices() +{ + int i; + drmDevicePtr device; + + /* Open the first AMD devcie to print driver information. */ + if (drm_amdgpu[0] >=0) { + /* Display AMD driver version information.*/ + drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]); + + if (retval == NULL) { + perror("Cannot get version for AMDGPU device"); + return; + } + + printf("Driver name: %s, Date: %s, Description: %s.\n", + retval->name, retval->date, retval->desc); + drmFreeVersion(retval); + } + + /* Display information of AMD devices */ + printf("Devices:\n"); + for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >=0; i++) + if (drmGetDevice2(drm_amdgpu[i], + DRM_DEVICE_GET_PCI_REVISION, + &device) == 0) { + if (device->bustype == DRM_BUS_PCI) { + printf("PCI "); + printf(" domain:%04x", + device->businfo.pci->domain); + printf(" bus:%02x", + device->businfo.pci->bus); + printf(" device:%02x", + device->businfo.pci->dev); + printf(" function:%01x", + device->businfo.pci->func); + printf(" vendor_id:%04x", + device->deviceinfo.pci->vendor_id); + printf(" device_id:%04x", + device->deviceinfo.pci->device_id); + printf(" subvendor_id:%04x", + device->deviceinfo.pci->subvendor_id); + printf(" subdevice_id:%04x", + device->deviceinfo.pci->subdevice_id); + printf(" revision_id:%02x", + device->deviceinfo.pci->revision_id); + printf("\n"); + } + drmFreeDevice(&device); + } +} + +/* Find a match AMD device in PCI bus + * Return the index of the device or -1 if not found + */ +static int amdgpu_find_device(uint8_t bus, uint8_t dev) +{ + int i; + drmDevicePtr device; + + for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >=0; i++) + if (drmGetDevice2(drm_amdgpu[i], + DRM_DEVICE_GET_PCI_REVISION, + &device) == 0) { + if (device->bustype == DRM_BUS_PCI) + if (device->businfo.pci->bus == bus && + device->businfo.pci->dev == dev) { + + drmFreeDevice(&device); + return i; + } + + drmFreeDevice(&device); + } + + return -1; +} /* The main() function for setting up and running the tests. * Returns a CUE_SUCCESS on successful running, another @@ -125,16 +297,12 @@ int main(int argc, char **argv) int i = 0; int suite_id = -1; /* By default run everything */ int test_id = -1; /* By default run all tests in the suite */ + int pci_bus_id = -1; /* By default PC bus ID is not specified */ + int pci_device_id = 0; /* By default PC device ID is zero */ + int display_devices = 0;/* By default not to display devices' info */ CU_pSuite pSuite = NULL; CU_pTest pTest = NULL; - - int aval = drmAvailable(); - - if (aval == 0) { - fprintf(stderr, "DRM driver is not available\n"); - exit(EXIT_FAILURE); - } - + int test_device_index; for (i = 0; i < MAX_CARDS_SUPPORTED; i++) drm_amdgpu[i] = -1; @@ -153,6 +321,18 @@ int main(int argc, char **argv) case 't': test_id = atoi(optarg); break; + case 'b': + pci_bus_id = atoi(optarg); + break; + case 'd': + pci_device_id = atoi(optarg); + break; + case 'p': + display_devices = 1; + break; + case 'r': + open_render_node = 1; + break; case '?': case 'h': fprintf(stderr, usage, argv[0]); @@ -163,35 +343,46 @@ int main(int argc, char **argv) } } - /* Try to open all possible radeon connections - * Right now: Open only the 0. - */ - printf("Try to open the card 0..\n"); - drm_amdgpu[0] = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); + if (amdgpu_open_devices(open_render_node) <= 0) { + perror("Cannot open AMDGPU device"); + exit(EXIT_FAILURE); + } if (drm_amdgpu[0] < 0) { - perror("Cannot open /dev/dri/card0\n"); + perror("Cannot open AMDGPU device"); exit(EXIT_FAILURE); } - /** Display version of DRM driver */ - drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]); - - if (retval == NULL) { - perror("Could not get information about DRM driver"); - exit(EXIT_FAILURE); + if (display_devices) { + amdgpu_print_devices(); + amdgpu_close_devices(); + exit(EXIT_SUCCESS); } - printf("DRM Driver: Name: [%s] : Date [%s] : Description [%s]\n", - retval->name, retval->date, retval->desc); + if (pci_bus_id > 0) { + /* A device was specified to run the test */ + test_device_index = amdgpu_find_device((uint8_t)pci_bus_id, + (uint8_t)pci_device_id); - drmFreeVersion(retval); + if (test_device_index >= 0) { + /* Most tests run on device of drm_amdgpu[0]. + * Swap the chosen device to drm_amdgpu[0]. + */ + i = drm_amdgpu[0]; + drm_amdgpu[0] = drm_amdgpu[test_device_index]; + drm_amdgpu[test_device_index] = i; + } else { + fprintf(stderr, + "The specified GPU device does not exist.\n"); + exit(EXIT_FAILURE); + } + } /* Initialize test suites to run */ /* initialize the CUnit test registry */ if (CUE_SUCCESS != CU_initialize_registry()) { - close(drm_amdgpu[0]); + amdgpu_close_devices(); return CU_get_error(); } @@ -200,7 +391,7 @@ int main(int argc, char **argv) fprintf(stderr, "suite registration failed - %s\n", CU_get_error_msg()); CU_cleanup_registry(); - close(drm_amdgpu[0]); + amdgpu_close_devices(); exit(EXIT_FAILURE); } @@ -222,7 +413,7 @@ int main(int argc, char **argv) fprintf(stderr, "Invalid test id: %d\n", test_id); CU_cleanup_registry(); - close(drm_amdgpu[0]); + amdgpu_close_devices(); exit(EXIT_FAILURE); } } else @@ -231,13 +422,13 @@ int main(int argc, char **argv) fprintf(stderr, "Invalid suite id : %d\n", suite_id); CU_cleanup_registry(); - close(drm_amdgpu[0]); + amdgpu_close_devices(); exit(EXIT_FAILURE); } } else CU_basic_run_tests(); CU_cleanup_registry(); - close(drm_amdgpu[0]); + amdgpu_close_devices(); return CU_get_error(); } diff --git a/lib/libdrm/tests/amdgpu/amdgpu_test.h b/lib/libdrm/tests/amdgpu/amdgpu_test.h index fca92ad02..e30e23120 100644 --- a/lib/libdrm/tests/amdgpu/amdgpu_test.h +++ b/lib/libdrm/tests/amdgpu/amdgpu_test.h @@ -35,6 +35,9 @@ /* Forward reference for array to keep "drm" handles */ extern int drm_amdgpu[MAX_CARDS_SUPPORTED]; +/* Global variables */ +extern int open_render_node; + /************************* Basic test suite ********************************/ /* diff --git a/lib/libdrm/tests/amdgpu/basic_tests.c b/lib/libdrm/tests/amdgpu/basic_tests.c index 11f6a63d8..bfda21b16 100644 --- a/lib/libdrm/tests/amdgpu/basic_tests.c +++ b/lib/libdrm/tests/amdgpu/basic_tests.c @@ -206,8 +206,13 @@ int suite_basic_tests_init(void) if (r == 0) return CUE_SUCCESS; - else + else { + if ((r == -EACCES) && (errno == EACCES)) + printf("\n\nError:%s. " + "Hint:Try to run this test program as root.", + strerror(errno)); return CUE_SINIT_FAILED; + } } int suite_basic_tests_clean(void) diff --git a/lib/libdrm/tests/amdgpu/bo_tests.c b/lib/libdrm/tests/amdgpu/bo_tests.c index 993895d84..74b5e77b2 100644 --- a/lib/libdrm/tests/amdgpu/bo_tests.c +++ b/lib/libdrm/tests/amdgpu/bo_tests.c @@ -65,8 +65,14 @@ int suite_bo_tests_init(void) r = amdgpu_device_initialize(drm_amdgpu[0], &major_version, &minor_version, &device_handle); - if (r) + if (r) { + if ((r == -EACCES) && (errno == EACCES)) + printf("\n\nError:%s. " + "Hint:Try to run this test program as root.", + strerror(errno)); + return CUE_SINIT_FAILED; + } req.alloc_size = BUFFER_SIZE; req.phys_alignment = BUFFER_ALIGN; @@ -146,6 +152,11 @@ static void amdgpu_bo_export_import_do_type(enum amdgpu_bo_handle_type type) static void amdgpu_bo_export_import(void) { + if (open_render_node) { + printf("(DRM render node is used. Skip export/Import test) "); + return; + } + amdgpu_bo_export_import_do_type(amdgpu_bo_handle_type_gem_flink_name); amdgpu_bo_export_import_do_type(amdgpu_bo_handle_type_dma_buf_fd); } diff --git a/lib/libdrm/tests/amdgpu/cs_tests.c b/lib/libdrm/tests/amdgpu/cs_tests.c index a01ee48a8..82c55aa8b 100644 --- a/lib/libdrm/tests/amdgpu/cs_tests.c +++ b/lib/libdrm/tests/amdgpu/cs_tests.c @@ -76,8 +76,14 @@ int suite_cs_tests_init(void) r = amdgpu_device_initialize(drm_amdgpu[0], &major_version, &minor_version, &device_handle); - if (r) + if (r) { + if ((r == -EACCES) && (errno == EACCES)) + printf("\n\nError:%s. " + "Hint:Try to run this test program as root.", + strerror(errno)); + return CUE_SINIT_FAILED; + } family_id = device_handle->info.family_id; /* VI asic POLARIS10/11 have specific external_rev_id */ diff --git a/lib/libdrm/tests/amdgpu/vce_tests.c b/lib/libdrm/tests/amdgpu/vce_tests.c index 491517059..de63aa152 100644 --- a/lib/libdrm/tests/amdgpu/vce_tests.c +++ b/lib/libdrm/tests/amdgpu/vce_tests.c @@ -94,8 +94,14 @@ int suite_vce_tests_init(void) r = amdgpu_device_initialize(drm_amdgpu[0], &major_version, &minor_version, &device_handle); - if (r) + if (r) { + if ((r == -EACCES) && (errno == EACCES)) + printf("\n\nError:%s. " + "Hint:Try to run this test program as root.", + strerror(errno)); + return CUE_SINIT_FAILED; + } family_id = device_handle->info.family_id; vce_harvest_config = device_handle->info.vce_harvest_config; diff --git a/lib/libdrm/tests/drmdevice.c b/lib/libdrm/tests/drmdevice.c index 72e706601..9dd5098a2 100644 --- a/lib/libdrm/tests/drmdevice.c +++ b/lib/libdrm/tests/drmdevice.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,7 @@ static void -print_device_info(drmDevicePtr device, int i) +print_device_info(drmDevicePtr device, int i, bool print_revision) { printf("device[%i]\n", i); printf("\tavailable_nodes %04x\n", device->available_nodes); @@ -56,7 +57,48 @@ print_device_info(drmDevicePtr device, int i) printf("\t\t\tdevice_id\t%04x\n", device->deviceinfo.pci->device_id); printf("\t\t\tsubvendor_id\t%04x\n", device->deviceinfo.pci->subvendor_id); printf("\t\t\tsubdevice_id\t%04x\n", device->deviceinfo.pci->subdevice_id); - printf("\t\t\trevision_id\t%02x\n", device->deviceinfo.pci->revision_id); + if (print_revision) + printf("\t\t\trevision_id\t%02x\n", device->deviceinfo.pci->revision_id); + else + printf("\t\t\trevision_id\tIGNORED\n"); + + } else if (device->bustype == DRM_BUS_USB) { + printf("\t\tusb\n"); + printf("\t\t\tbus\t%03u\n", device->businfo.usb->bus); + printf("\t\t\tdev\t%03u\n", device->businfo.usb->dev); + + printf("\tdeviceinfo\n"); + printf("\t\tusb\n"); + printf("\t\t\tvendor\t%04x\n", device->deviceinfo.usb->vendor); + printf("\t\t\tproduct\t%04x\n", device->deviceinfo.usb->product); + } else if (device->bustype == DRM_BUS_PLATFORM) { + char **compatible = device->deviceinfo.platform->compatible; + + printf("\t\tplatform\n"); + printf("\t\t\tfullname\t%s\n", device->businfo.platform->fullname); + + printf("\tdeviceinfo\n"); + printf("\t\tplatform\n"); + printf("\t\t\tcompatible\n"); + + while (*compatible) { + printf("\t\t\t\t%s\n", *compatible); + compatible++; + } + } else if (device->bustype == DRM_BUS_HOST1X) { + char **compatible = device->deviceinfo.platform->compatible; + + printf("\t\thost1x\n"); + printf("\t\t\tfullname\t%s\n", device->businfo.host1x->fullname); + + printf("\tdeviceinfo\n"); + printf("\t\tplatform\n"); + printf("\t\t\tcompatible\n"); + + while (*compatible) { + printf("\t\t\t\t%s\n", *compatible); + compatible++; + } } else { printf("Unknown/unhandled bustype\n"); } @@ -70,10 +112,10 @@ main(void) drmDevicePtr device; int fd, ret, max_devices; - max_devices = drmGetDevices(NULL, 0); + max_devices = drmGetDevices2(0, NULL, 0); if (max_devices <= 0) { - printf("drmGetDevices() has returned %d\n", max_devices); + printf("drmGetDevices2() has returned %d\n", max_devices); return -1; } @@ -83,15 +125,15 @@ main(void) return -1; } - ret = drmGetDevices(devices, max_devices); + ret = drmGetDevices2(0, devices, max_devices); if (ret < 0) { - printf("drmGetDevices() returned an error %d\n", ret); + printf("drmGetDevices2() returned an error %d\n", ret); free(devices); return -1; } for (int i = 0; i < ret; i++) { - print_device_info(devices[i], i); + print_device_info(devices[i], i, false); for (int j = 0; j < DRM_NODE_MAX; j++) { if (devices[i]->available_nodes & 1 << j) { @@ -102,8 +144,8 @@ main(void) continue; } - if (drmGetDevice(fd, &device) == 0) { - print_device_info(device, i); + if (drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, &device) == 0) { + print_device_info(device, i, true); drmFreeDevice(&device); } close(fd); diff --git a/lib/libdrm/tests/exynos/Makefile.am b/lib/libdrm/tests/exynos/Makefile.am index 357d6b8c2..b6361727b 100644 --- a/lib/libdrm/tests/exynos/Makefile.am +++ b/lib/libdrm/tests/exynos/Makefile.am @@ -1,4 +1,5 @@ AM_CFLAGS = \ + -pthread \ $(WARN_CFLAGS)\ -I $(top_srcdir)/include/drm \ -I $(top_srcdir)/libkms/ \ @@ -34,8 +35,7 @@ exynos_fimg2d_perf_LDADD = \ exynos_fimg2d_event_LDADD = \ $(top_builddir)/libdrm.la \ - $(top_builddir)/exynos/libdrm_exynos.la \ - -lpthread + $(top_builddir)/exynos/libdrm_exynos.la exynos_fimg2d_test_LDADD = \ $(top_builddir)/libdrm.la \ diff --git a/lib/libdrm/tests/kms/kms-universal-planes.c b/lib/libdrm/tests/kms/kms-universal-planes.c index d8e5fc48f..89057bb50 100644 --- a/lib/libdrm/tests/kms/kms-universal-planes.c +++ b/lib/libdrm/tests/kms/kms-universal-planes.c @@ -212,9 +212,9 @@ int main(int argc, char *argv[]) printf("Planes: %u\n", device->num_planes); for (i = 0; i < device->num_planes; i++) { - struct kms_plane *plane = device->planes[i]; const char *type = NULL; + plane = device->planes[i]; switch (plane->type) { case DRM_PLANE_TYPE_OVERLAY: type = "overlay"; diff --git a/lib/libdrm/tests/modetest/Makefile.am b/lib/libdrm/tests/modetest/Makefile.am index 9686ccb93..4b296c837 100644 --- a/lib/libdrm/tests/modetest/Makefile.am +++ b/lib/libdrm/tests/modetest/Makefile.am @@ -3,6 +3,7 @@ include Makefile.sources AM_CFLAGS = $(filter-out -Wpointer-arith, $(WARN_CFLAGS)) AM_CFLAGS += \ + -pthread \ -I$(top_srcdir)/include/drm \ -I$(top_srcdir)/tests \ -I$(top_srcdir) @@ -20,5 +21,4 @@ modetest_SOURCES = $(MODETEST_FILES) modetest_LDADD = \ $(top_builddir)/libdrm.la \ $(top_builddir)/tests/util/libutil.la \ - $(CAIRO_LIBS) \ - -lpthread + $(CAIRO_LIBS) diff --git a/lib/libdrm/tests/modetest/modetest.c b/lib/libdrm/tests/modetest/modetest.c index dedd28621..c390d875e 100644 --- a/lib/libdrm/tests/modetest/modetest.c +++ b/lib/libdrm/tests/modetest/modetest.c @@ -704,6 +704,7 @@ struct pipe_arg { }; struct plane_arg { + uint32_t plane_id; /* the id of plane to use */ uint32_t crtc_id; /* the id of CRTC to bind to */ bool has_position; int32_t x, y; @@ -958,7 +959,7 @@ static int set_plane(struct device *dev, struct plane_arg *p) { drmModePlane *ovr; uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; - uint32_t plane_id = 0; + uint32_t plane_id; struct bo *plane_bo; uint32_t plane_flags = 0; int crtc_x, crtc_y, crtc_w, crtc_h; @@ -982,16 +983,26 @@ static int set_plane(struct device *dev, struct plane_arg *p) return -1; } - for (i = 0; i < dev->resources->plane_res->count_planes && !plane_id; i++) { + plane_id = p->plane_id; + + for (i = 0; i < dev->resources->plane_res->count_planes; i++) { ovr = dev->resources->planes[i].plane; - if (!ovr || !format_support(ovr, p->fourcc)) + if (!ovr) continue; - if ((ovr->possible_crtcs & (1 << pipe)) && !ovr->crtc_id) + if (plane_id && plane_id != ovr->plane_id) + continue; + + if (!format_support(ovr, p->fourcc)) + continue; + + if ((ovr->possible_crtcs & (1 << pipe)) && !ovr->crtc_id) { plane_id = ovr->plane_id; + break; + } } - if (!plane_id) { + if (i == dev->resources->plane_res->count_planes) { fprintf(stderr, "no unused plane available for CRTC %u\n", crtc->crtc->crtc_id); return -1; @@ -1359,6 +1370,11 @@ static int parse_plane(struct plane_arg *plane, const char *p) { char *end; + plane->plane_id = strtoul(p, &end, 10); + if (*end != '@') + return -EINVAL; + + p = end + 1; plane->crtc_id = strtoul(p, &end, 10); if (*end != ':') return -EINVAL; @@ -1430,7 +1446,7 @@ static void usage(char *name) fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n"); fprintf(stderr, "\n Test options:\n\n"); - fprintf(stderr, "\t-P :x[++][*][@]\tset a plane\n"); + fprintf(stderr, "\t-P @:x[++][*][@]\tset a plane\n"); fprintf(stderr, "\t-s [,][@]:[-][@]\tset a mode\n"); fprintf(stderr, "\t-C\ttest hw cursor\n"); fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); diff --git a/lib/libdrm/tests/nouveau/Makefile.am b/lib/libdrm/tests/nouveau/Makefile.am index c4f6e299f..3c799a81d 100644 --- a/lib/libdrm/tests/nouveau/Makefile.am +++ b/lib/libdrm/tests/nouveau/Makefile.am @@ -1,14 +1,14 @@ -AM_CPPFLAGS = \ +AM_CFLAGS = \ + -pthread \ + $(WARN_CFLAGS) \ -I$(top_srcdir)/include/drm \ -I$(top_srcdir)/nouveau \ -I$(top_srcdir) -AM_CFLAGS = $(WARN_CFLAGS) - LDADD = \ ../../nouveau/libdrm_nouveau.la \ ../../libdrm.la \ - -ldl -lpthread + -ldl TESTS = threaded diff --git a/lib/libdrm/tests/util/kms.c b/lib/libdrm/tests/util/kms.c index 4d89ac8f6..959b68815 100644 --- a/lib/libdrm/tests/util/kms.c +++ b/lib/libdrm/tests/util/kms.c @@ -144,6 +144,7 @@ static const char * const modules[] = { "vc4", "virtio_gpu", "mediatek", + "meson", }; int util_open(const char *device, const char *module)