aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 02:04:22 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 02:04:22 +0000
commit3c03f1263bfb4aa8c7e211e16773bc5be23d39fe (patch)
tree016f75b88ffb77530b6b58039d84238c213c31cc
parent18a679b092f9e665c590a055c4f0eb751affd9d3 (diff)
parent2e9888d043bb7b9c6ca8d0ba2c4fa7bb151ec95b (diff)
downloadlibdrm-android12-mainline-resolv-release.tar.gz
Change-Id: I7d1bd927202cbef73403d1168cfc906d406d7b07
-rw-r--r--.gitignore109
-rw-r--r--.gitlab-ci.yml267
-rw-r--r--.gitlab-ci/debian-install.sh66
-rw-r--r--Android.bp41
-rw-r--r--LICENSE40
-rw-r--r--METADATA3
-rw-r--r--Makefile.am176
-rw-r--r--README.rst30
-rw-r--r--RELEASING29
-rw-r--r--amdgpu/Android.bp9
-rw-r--r--amdgpu/Makefile.am53
-rw-r--r--[-rwxr-xr-x]amdgpu/amdgpu-symbols.txt (renamed from amdgpu/amdgpu-symbol-check)21
-rw-r--r--amdgpu/amdgpu.h33
-rw-r--r--amdgpu/amdgpu_cs.c67
-rw-r--r--amdgpu/amdgpu_internal.h2
-rw-r--r--amdgpu/meson.build13
-rwxr-xr-xautogen.sh20
-rw-r--r--configure.ac605
-rw-r--r--core-symbols.txt198
-rw-r--r--data/Android.bp9
-rw-r--r--data/Makefile.am25
-rw-r--r--data/amdgpu.ids87
-rw-r--r--etnaviv/Android.bp9
-rw-r--r--etnaviv/Makefile.am28
-rw-r--r--etnaviv/Makefile.sources1
-rw-r--r--[-rwxr-xr-x]etnaviv/etnaviv-symbols.txt (renamed from etnaviv/etnaviv-symbol-check)19
-rw-r--r--etnaviv/etnaviv_drm.h289
-rw-r--r--etnaviv/etnaviv_priv.h2
-rw-r--r--etnaviv/meson.build10
-rw-r--r--exynos/Makefile.am29
-rwxr-xr-xexynos/exynos-symbol-check42
-rw-r--r--exynos/exynos-symbols.txt23
-rw-r--r--exynos/meson.build11
-rw-r--r--freedreno/Android.bp9
-rw-r--r--freedreno/Makefile.am33
-rw-r--r--[-rwxr-xr-x]freedreno/freedreno-symbols.txt (renamed from freedreno/freedreno-symbol-check)20
-rw-r--r--freedreno/meson.build11
-rw-r--r--include/drm/amdgpu_drm.h68
-rw-r--r--include/drm/drm.h5
-rw-r--r--include/drm/drm_fourcc.h507
-rw-r--r--include/drm/drm_mode.h147
-rw-r--r--include/drm/nouveau_drm.h77
-rw-r--r--intel/Android.bp10
-rw-r--r--intel/Makefile.am75
-rw-r--r--intel/i915_pciids.h370
-rw-r--r--[-rwxr-xr-x]intel/intel-symbols.txt (renamed from intel/intel-symbol-check)19
-rw-r--r--intel/intel_bufmgr_gem.c45
-rw-r--r--intel/intel_chipset.c6
-rw-r--r--intel/intel_chipset.h1
-rw-r--r--intel/meson.build30
-rwxr-xr-xintel/tests/test-batch.sh2
-rw-r--r--libkms/Android.bp9
-rw-r--r--libkms/Makefile.am45
-rwxr-xr-xlibkms/kms-symbol-check27
-rw-r--r--libkms/kms-symbols.txt8
-rw-r--r--libkms/meson.build11
-rw-r--r--m4/.gitignore5
-rw-r--r--man/Makefile.am62
-rw-r--r--man/drm-kms.7.rst229
-rw-r--r--man/drm-kms.xml342
-rw-r--r--man/drm-memory.7.rst322
-rw-r--r--man/drm-memory.xml430
-rw-r--r--man/drm.7.rst91
-rw-r--r--man/drm.xml137
-rw-r--r--man/drmAvailable.3.rst41
-rw-r--r--man/drmAvailable.xml75
-rw-r--r--man/drmHandleEvent.3.rst62
-rw-r--r--man/drmHandleEvent.xml102
-rw-r--r--man/drmModeGetResources.3.rst92
-rw-r--r--man/drmModeGetResources.xml139
-rw-r--r--man/meson.build57
-rw-r--r--meson.build72
-rw-r--r--nouveau/Android.bp9
-rw-r--r--nouveau/Makefile.am35
-rw-r--r--nouveau/meson.build11
-rw-r--r--[-rwxr-xr-x]nouveau/nouveau-symbols.txt (renamed from nouveau/nouveau-symbol-check)19
-rw-r--r--nouveau/private.h2
-rw-r--r--omap/Android.bp9
-rw-r--r--omap/Makefile.am26
-rw-r--r--omap/meson.build11
-rwxr-xr-xomap/omap-symbol-check37
-rw-r--r--omap/omap-symbols.txt18
-rw-r--r--radeon/Android.bp9
-rw-r--r--radeon/Makefile.am49
-rw-r--r--radeon/meson.build11
-rw-r--r--[-rwxr-xr-x]radeon/radeon-symbols.txt (renamed from radeon/radeon-symbol-check)19
-rw-r--r--symbols-check.py130
-rw-r--r--tegra/Android.bp9
-rw-r--r--tegra/Makefile.am27
-rw-r--r--tegra/meson.build11
-rwxr-xr-xtegra/tegra-symbol-check35
-rw-r--r--tegra/tegra-symbols.txt13
-rw-r--r--tests/Android.bp9
-rw-r--r--tests/Makefile.am53
-rw-r--r--tests/amdgpu/Makefile.am38
-rw-r--r--tests/amdgpu/amdgpu_test.c90
-rw-r--r--tests/amdgpu/amdgpu_test.h58
-rw-r--r--tests/amdgpu/basic_tests.c902
-rw-r--r--tests/amdgpu/bo_tests.c3
-rw-r--r--tests/amdgpu/cs_tests.c7
-rw-r--r--tests/amdgpu/deadlock_tests.c78
-rw-r--r--tests/amdgpu/decode_messages.h10
-rw-r--r--tests/amdgpu/meson.build4
-rw-r--r--tests/amdgpu/ras_tests.c729
-rw-r--r--tests/amdgpu/security_tests.c485
-rw-r--r--tests/amdgpu/syncobj_tests.c2
-rw-r--r--tests/amdgpu/vce_tests.c6
-rw-r--r--tests/amdgpu/vcn_tests.c70
-rw-r--r--tests/amdgpu/vm_tests.c12
-rw-r--r--tests/etnaviv/Makefile.am43
-rw-r--r--tests/etnaviv/etnaviv_2d_test.c72
-rw-r--r--tests/etnaviv/etnaviv_bo_cache_test.c2
-rw-r--r--tests/exynos/Makefile.am48
-rw-r--r--tests/kms/Makefile.am37
-rw-r--r--tests/kms/kms-steal-crtc.c2
-rw-r--r--tests/kms/kms-universal-planes.c2
-rw-r--r--tests/kms/libkms-test-screen.c4
-rw-r--r--tests/kmstest/Makefile.am26
-rw-r--r--tests/meson.build10
-rw-r--r--tests/modeprint/Makefile.am20
-rw-r--r--tests/modetest/Android.bp9
-rw-r--r--tests/modetest/Makefile.am25
-rw-r--r--tests/modetest/modetest.c858
-rw-r--r--tests/nouveau/Makefile.am17
-rw-r--r--tests/nouveau/threaded.c4
-rw-r--r--tests/proptest/Android.bp9
-rw-r--r--tests/proptest/Makefile.am22
-rw-r--r--tests/radeon/Makefile.am15
-rw-r--r--tests/random.c120
-rw-r--r--tests/tegra/Makefile.am15
-rw-r--r--tests/util/Android.bp9
-rw-r--r--tests/util/Makefile.am13
-rw-r--r--tests/util/kms.c3
-rw-r--r--tests/util/pattern.c7
-rw-r--r--tests/vbltest/Makefile.am20
-rw-r--r--tests/vbltest/vbltest.c2
-rw-r--r--vc4/Makefile.am35
-rw-r--r--xf86atomic.h1
-rw-r--r--xf86drm.c460
-rw-r--r--xf86drm.h67
-rw-r--r--xf86drmMode.c67
-rw-r--r--xf86drmMode.h158
142 files changed, 6192 insertions, 5215 deletions
diff --git a/.gitignore b/.gitignore
index 811348ab..0ec9e7f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,110 +1 @@
-*.1
-*.3
-*.5
-*.7
-*.flags
-*.ko
-*.ko.cmd
-*.la
-*.lo
-*.log
-*.mod.c
-*.mod.o
-*.o
-*.o.cmd
-*.sw?
-*.trs
-*~
-.*check*
-.*install*
-.depend
-.deps
-.libs
-.tmp_versions
-/_build*
/build*
-Makefile
-Makefile.in
-TAGS
-aclocal.m4
-autom4te.cache
-bsd-core/*/@
-bsd-core/*/machine
-build-aux
-bus_if.h
-compile
-config.guess
-config.h
-config.h.in
-config.log
-config.status
-config.sub
-configure
-configure.lineno
-cscope.*
-depcomp
-device_if.h
-drm.kld
-drm_pciids.h
-export_syms
-i915.kld
-install-sh
-libdrm.pc
-libdrm/config.h.in
-libdrm_amdgpu.pc
-libdrm_etnaviv.pc
-libdrm_exynos.pc
-libdrm_freedreno.pc
-libdrm_intel.pc
-libdrm_nouveau.pc
-libdrm_omap.pc
-libdrm_radeon.pc
-libdrm_vc4.pc
-libkms.pc
-libtool
-ltmain.sh
-mach64.kld
-man/*.3
-man/.man_fixup
-mga.kld
-missing
-mkinstalldirs
-opt_drm.h
-pci_if.h
-r128.kld
-radeon.kld
-savage.kld
-sis.kld
-stamp-h1
-tdfx.kld
-tests/amdgpu/amdgpu_test
-tests/auth
-tests/dristat
-tests/drmdevice
-tests/drmsl
-tests/drmstat
-tests/etnaviv/etnaviv_2d_test
-tests/etnaviv/etnaviv_bo_cache_test
-tests/etnaviv/etnaviv_cmd_stream_test
-tests/exynos/exynos_fimg2d_event
-tests/exynos/exynos_fimg2d_perf
-tests/exynos/exynos_fimg2d_test
-tests/getclient
-tests/getstats
-tests/getversion
-tests/hash
-tests/kms/kms-steal-crtc
-tests/kms/kms-universal-planes
-tests/kmstest/kmstest
-tests/lock
-tests/modeprint/modeprint
-tests/modetest/modetest
-tests/name_from_fd
-tests/openclose
-tests/proptest/proptest
-tests/radeon/radeon_ttm
-tests/random
-tests/setversion
-tests/updatedraw
-tests/vbltest/vbltest
-via.kld
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ac2a9d2d..b99dc912 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,159 +1,130 @@
-.artifacts-meson: &artifacts-meson
- when: always
- paths:
- - _build/meson-logs
+# This is the tag of the docker image used for the build jobs. If the
+# image doesn't exist yet, the containers stage generates it.
+#
+# In order to generate a new image, one should generally change the tag.
+# While removing the image from the registry would also work, that's not
+# recommended except for ephemeral images during development: Replacing
+# an image after a significant amount of time might pull in newer
+# versions of gcc/clang or other packages, which might break the build
+# with older commits using the same tag.
+#
+# After merging a change resulting in generating a new image to the
+# main repository, it's recommended to remove the image from the source
+# repository's container registry, so that the image from the main
+# repository's registry will be used there as well.
+variables:
+ UPSTREAM_REPO: mesa/drm
+ DEBIAN_TAG: "2020-11-15"
+ DEBIAN_VERSION: buster-slim
+ DEBIAN_IMAGE: "$CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG"
-.artifacts-autotools: &artifacts-autotools
- when: always
- paths:
- - _build/*.log
- - _build/*/*.log
- - _build/*/*/*.log
+include:
+ - project: 'wayland/ci-templates'
+ ref: 0a9bdd33a98f05af6761ab118b5074952242aab0
+ file: '/templates/debian.yml'
-.meson-build: &meson-build
- - meson _build
- -D amdgpu=true
- -D cairo-tests=true
- -D etnaviv=true
- -D exynos=true
- -D freedreno=true
- -D freedreno-kgsl=true
- -D intel=true
- -D libkms=true
- -D man-pages=true
- -D nouveau=true
- -D omap=true
- -D radeon=true
- -D tegra=true
- -D udev=true
- -D valgrind=true
- -D vc4=true
- -D vmwgfx=true
- - ninja -C _build
- - ninja -C _build test
+stages:
+ - containers
+ - build
-.autotools-build: &autotools-build
- - mkdir _build
- - cd _build
- - ../autogen.sh
- --enable-udev
- --enable-libkms
- --enable-intel
- --enable-radeon
- --enable-amdgpu
- --enable-nouveau
- --enable-vmwgfx
- --enable-omap-experimental-api
- --enable-exynos-experimental-api
- --enable-freedreno
- --enable-freedreno-kgsl
- --enable-tegra-experimental-api
- --enable-vc4
- --enable-etnaviv-experimental-api
- - make
- - make check
-latest-meson:
- stage: build
- image: archlinux/base:latest
- before_script:
- - pacman -Syu --noconfirm --needed
- base-devel
- meson
- libpciaccess
- libxslt docbook-xsl
- valgrind
- libatomic_ops
- cairo cunit
- script: *meson-build
+# When & how to run the CI
+.ci-run-policy:
+ except:
+ - schedules
+ retry:
+ max: 2
+ when:
+ - runner_system_failure
-latest-autotools:
+# CONTAINERS
+
+debian:
+ stage: containers
+ extends:
+ - .ci-run-policy
+ - .debian@container-ifnot-exists
+ variables:
+ GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
+ DEBIAN_EXEC: 'bash .gitlab-ci/debian-install.sh'
+
+
+# BUILD
+
+.meson-build:
stage: build
- image: archlinux/base:latest
- artifacts: *artifacts-autotools
+ variables:
+ GIT_DEPTH: 10
+ script:
+ - meson build
+ -D amdgpu=true
+ -D cairo-tests=true
+ -D etnaviv=true
+ -D exynos=true
+ -D freedreno=true
+ -D freedreno-kgsl=true
+ -D intel=true
+ -D libkms=true
+ -D man-pages=true
+ -D nouveau=true
+ -D omap=true
+ -D radeon=true
+ -D tegra=true
+ -D udev=true
+ -D valgrind=auto
+ -D vc4=true
+ -D vmwgfx=true
+ ${CROSS+--cross /cross_file-$CROSS.txt}
+ - ninja -C build
+ - ninja -C build test
+ - DESTDIR=$PWD/install ninja -C build install
+ artifacts:
+ when: on_failure
+ paths:
+ - build/meson-logs/*
+
+meson-x86_64:
+ extends:
+ - .ci-run-policy
+ - .meson-build
+ image: $DEBIAN_IMAGE
+ needs:
+ - debian
+
+meson-i386:
+ extends: meson-x86_64
+ variables:
+ CROSS: i386
+
+meson-aarch64:
+ extends: meson-x86_64
+ variables:
+ CROSS: arm64
+
+meson-armhf:
+ extends: meson-x86_64
+ variables:
+ CROSS: armhf
+
+meson-ppc64el:
+ extends: meson-x86_64
+ variables:
+ CROSS: ppc64el
+
+meson-arch-daily:
+ rules:
+ - if: '$SCHEDULE == "arch-daily"'
+ when: on_success
+ - when: never
+ image: archlinux/base
before_script:
- pacman -Syu --noconfirm --needed
base-devel
- libpciaccess
- libxslt docbook-xsl
- valgrind
+ cairo
+ cunit
libatomic_ops
- cairo cunit
- xorg-util-macros
- git # autogen.sh depends on git
- script: *autotools-build
-
-oldest-meson:
- stage: build
- image: debian:stable
- artifacts: *artifacts-meson
- before_script:
- - printf > /etc/dpkg/dpkg.cfg.d/99-exclude-cruft "%s\n"
- 'path-exclude=/usr/share/doc/*'
- 'path-exclude=/usr/share/man/*'
- - printf > /usr/sbin/policy-rc.d "%s\n"
- '#!/bin/sh'
- 'exit 101'
- - chmod +x /usr/sbin/policy-rc.d
- - apt-get update
- - apt-get -y --no-install-recommends install
- build-essential
- pkg-config
- xsltproc
- libxslt1-dev docbook-xsl
- valgrind
- libatomic-ops-dev
- libcairo2-dev libcunit1-dev
- ninja-build
- python3 python3-pip
- wget
- # We need `--no-check-certificate` here because Debian's CA list is
- # too old to know about LetsEncrypt's CA, so it refuses to connect
- # to FreeDesktop.org
- - LIBPCIACCESS_VERSION=libpciaccess-0.10 &&
- wget --no-check-certificate https://xorg.freedesktop.org/releases/individual/lib/$LIBPCIACCESS_VERSION.tar.bz2 &&
- tar -jxvf $LIBPCIACCESS_VERSION.tar.bz2 &&
- (cd $LIBPCIACCESS_VERSION && ./configure --prefix=$HOME/prefix && make install)
- - pip3 install wheel setuptools
- - pip3 install meson==0.43
- - export PKG_CONFIG_PATH=$HOME/prefix/lib/pkgconfig:$HOME/prefix/share/pkgconfig
- - export LD_LIBRARY_PATH="$HOME/prefix/lib:$LD_LIBRARY_PATH"
- script: *meson-build
-
-oldest-autotools:
- stage: build
- image: debian:stable
- artifacts: *artifacts-autotools
- before_script:
- - printf > /etc/dpkg/dpkg.cfg.d/99-exclude-cruft "%s\n"
- 'path-exclude=/usr/share/doc/*'
- 'path-exclude=/usr/share/man/*'
- - printf > /usr/sbin/policy-rc.d "%s\n"
- '#!/bin/sh'
- 'exit 101'
- - chmod +x /usr/sbin/policy-rc.d
- - apt-get update
- - apt-get -y --no-install-recommends install
- build-essential
- automake
- autoconf
- libtool
- pkg-config
- xsltproc
- libxslt1-dev docbook-xsl
+ libpciaccess
+ meson
valgrind
- libatomic-ops-dev
- libcairo2-dev libcunit1-dev
- wget
- xutils-dev
- git # autogen.sh depends on git
- # We need `--no-check-certificate` here because Debian's CA list is
- # too old to know about LetsEncrypt's CA, so it refuses to connect
- # to FreeDesktop.org
- - LIBPCIACCESS_VERSION=libpciaccess-0.10 &&
- wget --no-check-certificate https://xorg.freedesktop.org/releases/individual/lib/$LIBPCIACCESS_VERSION.tar.bz2 &&
- tar -jxvf $LIBPCIACCESS_VERSION.tar.bz2 &&
- (cd $LIBPCIACCESS_VERSION && ./configure --prefix=$HOME/prefix && make install)
- - export PKG_CONFIG_PATH=$HOME/prefix/lib/pkgconfig:$HOME/prefix/share/pkgconfig
- - export LD_LIBRARY_PATH="$HOME/prefix/lib:$LD_LIBRARY_PATH"
- script: *autotools-build
+ python-docutils
+ extends: .meson-build
diff --git a/.gitlab-ci/debian-install.sh b/.gitlab-ci/debian-install.sh
new file mode 100644
index 00000000..886e808f
--- /dev/null
+++ b/.gitlab-ci/debian-install.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+set -o errexit
+set -o xtrace
+
+export DEBIAN_FRONTEND=noninteractive
+
+CROSS_ARCHITECTURES=(i386 armhf arm64 ppc64el)
+for arch in ${CROSS_ARCHITECTURES[@]}; do
+ dpkg --add-architecture $arch
+done
+
+apt-get install -y \
+ ca-certificates
+
+sed -i -e 's/http:\/\/deb/https:\/\/deb/g' /etc/apt/sources.list
+echo 'deb https://deb.debian.org/debian buster-backports main' >/etc/apt/sources.list.d/backports.list
+
+apt-get update
+
+# Use newer packages from backports by default
+cat >/etc/apt/preferences <<EOF
+Package: *
+Pin: release a=buster-backports
+Pin-Priority: 500
+EOF
+
+apt-get dist-upgrade -y
+
+apt-get install -y --no-remove \
+ build-essential \
+ docbook-xsl \
+ libatomic-ops-dev \
+ libcairo2-dev \
+ libcunit1-dev \
+ libpciaccess-dev \
+ meson \
+ ninja-build \
+ pkg-config \
+ python3 \
+ python3-pip \
+ python3-wheel \
+ python3-setuptools \
+ python3-docutils \
+ valgrind
+
+for arch in ${CROSS_ARCHITECTURES[@]}; do
+ cross_file=/cross_file-$arch.txt
+
+ # Cross-build libdrm deps
+ apt-get install -y --no-remove \
+ libcairo2-dev:$arch \
+ libpciaccess-dev:$arch \
+ crossbuild-essential-$arch
+
+ # Generate cross build files for Meson
+ /usr/share/meson/debcrossgen --arch $arch -o $cross_file
+
+ # Work around a bug in debcrossgen that should be fixed in the next release
+ if [ $arch = i386 ]; then
+ sed -i "s|cpu_family = 'i686'|cpu_family = 'x86'|g" $cross_file
+ fi
+done
+
+
+# Test that the oldest Meson version we claim to support is still supported
+pip3 install meson==0.43
diff --git a/Android.bp b/Android.bp
index 158f2660..dbac5626 100644
--- a/Android.bp
+++ b/Android.bp
@@ -21,6 +21,35 @@
// IN THE SOFTWARE.
//
+package {
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "external_libdrm_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-BSD",
+ "SPDX-license-identifier-MIT",
+ "legacy_unencumbered",
+ ],
+ // large-scale-change unable to identify any license_text files
+}
+
subdirs = ["*"]
build = ["Android.sources.bp"]
@@ -47,6 +76,14 @@ cc_defaults {
export_system_include_dirs: ["."],
}
+cc_library_headers {
+ name: "libdrm_headers",
+ vendor_available: true,
+ host_supported: true,
+ defaults: ["libdrm_defaults"],
+ export_include_dirs: ["include/drm", "android"],
+}
+
// Library for the device
cc_library {
name: "libdrm",
@@ -66,4 +103,8 @@ cc_library {
"-Wno-sign-compare",
"-Wno-tautological-compare",
],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.virt",
+ ],
}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..917b95c3
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,40 @@
+libdrm is under MIT license.
+
+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 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+
+---------------------------------------------------------------------------
+intel/uthash.h
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 00000000..d97975ca
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 730de1f2..00000000
--- a/Makefile.am
+++ /dev/null
@@ -1,176 +0,0 @@
-# Copyright 2005 Adam Jackson.
-#
-# 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
-# on the rights to use, copy, modify, merge, publish, distribute, sub
-# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
-# ADAM JACKSON 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 Makefile.sources
-
-ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
-
-AM_MAKEFLAGS = -s
-AM_DISTCHECK_CONFIGURE_FLAGS = \
- --enable-udev \
- --enable-libkms \
- --enable-intel \
- --enable-radeon \
- --enable-amdgpu \
- --enable-nouveau \
- --enable-vc4 \
- --enable-vmwgfx \
- --enable-omap-experimental-api \
- --enable-exynos-experimental-api \
- --enable-freedreno \
- --enable-freedreno-kgsl\
- --enable-tegra-experimental-api \
- --enable-etnaviv-experimental-api \
- --enable-install-test-programs \
- --enable-cairo-tests \
- --enable-manpages \
- --enable-valgrind
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm.pc
-
-if HAVE_LIBKMS
-LIBKMS_SUBDIR = libkms
-endif
-
-if HAVE_INTEL
-INTEL_SUBDIR = intel
-endif
-
-if HAVE_NOUVEAU
-NOUVEAU_SUBDIR = nouveau
-endif
-
-if HAVE_RADEON
-RADEON_SUBDIR = radeon
-endif
-
-if HAVE_AMDGPU
-AMDGPU_SUBDIR = amdgpu
-endif
-
-if HAVE_OMAP
-OMAP_SUBDIR = omap
-endif
-
-if HAVE_EXYNOS
-EXYNOS_SUBDIR = exynos
-endif
-
-if HAVE_FREEDRENO
-FREEDRENO_SUBDIR = freedreno
-endif
-
-if HAVE_TEGRA
-TEGRA_SUBDIR = tegra
-endif
-
-if HAVE_VC4
-VC4_SUBDIR = vc4
-endif
-
-if HAVE_ETNAVIV
-ETNAVIV_SUBDIR = etnaviv
-endif
-
-if BUILD_MANPAGES
-if HAVE_MANPAGES_STYLESHEET
-MAN_SUBDIR = man
-endif
-endif
-
-SUBDIRS = \
- . \
- $(LIBKMS_SUBDIR) \
- $(INTEL_SUBDIR) \
- $(NOUVEAU_SUBDIR) \
- $(RADEON_SUBDIR) \
- $(AMDGPU_SUBDIR) \
- $(OMAP_SUBDIR) \
- $(EXYNOS_SUBDIR) \
- $(FREEDRENO_SUBDIR) \
- $(TEGRA_SUBDIR) \
- $(VC4_SUBDIR) \
- $(ETNAVIV_SUBDIR) \
- data \
- tests \
- $(MAN_SUBDIR)
-
-libdrm_la_LTLIBRARIES = libdrm.la
-libdrm_ladir = $(libdir)
-libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined
-libdrm_la_LIBADD = @CLOCK_LIB@ -lm
-
-libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- $(VALGRIND_CFLAGS)
-
-libdrm_la_SOURCES = $(LIBDRM_FILES)
-
-libdrmincludedir = ${includedir}
-libdrminclude_HEADERS = $(LIBDRM_H_FILES)
-
-klibdrmincludedir = ${includedir}/libdrm
-klibdrminclude_HEADERS = $(LIBDRM_INCLUDE_H_FILES)
-
-if HAVE_VMWGFX
-klibdrminclude_HEADERS += $(LIBDRM_INCLUDE_VMWGFX_H_FILES)
-endif
-
-EXTRA_DIST = \
- include/drm/README \
- amdgpu/meson.build \
- data/meson.build \
- etnaviv/meson.build \
- exynos/meson.build \
- freedreno/meson.build \
- intel/meson.build \
- libkms/meson.build \
- man/meson.build \
- nouveau/meson.build \
- omap/meson.build \
- radeon/meson.build \
- tegra/meson.build \
- tests/amdgpu/meson.build \
- tests/etnaviv/meson.build \
- tests/exynos/meson.build \
- tests/kms/meson.build \
- tests/kmstest/meson.build \
- tests/meson.build \
- tests/modeprint/meson.build \
- tests/modetest/meson.build \
- tests/nouveau/meson.build \
- tests/proptest/meson.build \
- tests/radeon/meson.build \
- tests/tegra/meson.build \
- tests/util/meson.build \
- tests/vbltest/meson.build \
- vc4/meson.build \
- meson.build \
- meson_options.txt
-
-copy-headers :
- cp -r $(kernel_source)/include/uapi/drm/*.h $(top_srcdir)/include/drm/
-
-commit-headers : copy-headers
- git add include/drm/*.h
- git commit -am "Copy headers from kernel $$(GIT_DIR=$(kernel_source)/.git git describe)"
diff --git a/README.rst b/README.rst
index e47cb241..da995d0b 100644
--- a/README.rst
+++ b/README.rst
@@ -17,11 +17,7 @@ the Mesa drivers, the X drivers, libva and similar projects.
Compiling
---------
-libdrm has two build systems, a legacy autotools build system, and a newer
-meson build system. The meson build system is much faster, and offers a
-slightly different interface, but otherwise provides an equivalent feature set.
-
-To use it:
+To set up meson:
meson builddir/
@@ -35,27 +31,3 @@ Then use ninja to build and install:
If you are installing into a system location you will need to run install
separately, and as root.
-
-
-Alternatively you can invoke autotools configure:
-
- ./configure
-
-By default, libdrm will install into the /usr/local/ prefix. If you
-want to install this DRM to replace your system copy, pass
---prefix=/usr and --exec-prefix=/ to configure. If you are building
-libdrm from a git checkout, you first need to run the autogen.sh
-script. You can pass any options to autogen.sh that you would other
-wise pass to configure, or you can just re-run configure with the
-options you need once autogen.sh finishes.
-
-Next step is to build libdrm:
-
- make
-
-and once make finishes successfully, install the package using
-
- make install
-
-If you are installing into a system location, you will need to be root
-to perform the install step.
diff --git a/RELEASING b/RELEASING
index 7e03e3b9..903c1761 100644
--- a/RELEASING
+++ b/RELEASING
@@ -9,33 +9,22 @@ However, this is up to whoever is driving the feature in question.
Follow these steps to release a new version of libdrm:
- 1) Bump the version number in configure.ac and meson.build. We seem
- to have settled for 2.4.x as the versioning scheme for libdrm, so
- just bump the micro version.
+ 1) Bump the version number in meson.build. We seem to have settled for
+ 2.4.x as the versioning scheme for libdrm, so just bump the micro
+ version.
- 2) Run autoconf and then re-run ./configure so the build system
- picks up the new version number.
+ 2) Run `ninja -C builddir/ dist` to generate the tarballs.
+ Make sure that the version number of the tarball name in
+ builddir/meson-dist/ matches the number you bumped to. Move that
+ tarball to the libdrm repo root for the release script to pick up.
- 3) Verify that the code passes "make distcheck". Running "make
- distcheck" should result in no warnings or errors and end with a
- message of the form:
-
- =============================================
- libdrm-X.Y.Z archives ready for distribution:
- libdrm-X.Y.Z.tar.gz
- libdrm-X.Y.Z.tar.bz2
- =============================================
-
- Make sure that the version number reported by distcheck and in
- the tarball names matches the number you bumped to in configure.ac.
-
- 4) Push the updated master branch with the bumped version number:
+ 3) Push the updated master branch with the bumped version number:
git push origin master
assuming the remote for the upstream libdrm repo is called origin.
- 5) Use the release.sh script from the xorg/util/modular repo to
+ 4) Use the release.sh script from the xorg/util/modular repo to
upload the tarballs to the freedesktop.org download area and
create an announce email template. The script takes one argument:
the path to the libdrm checkout. So, if a checkout of modular is
diff --git a/amdgpu/Android.bp b/amdgpu/Android.bp
index 976f03e9..94f5668d 100644
--- a/amdgpu/Android.bp
+++ b/amdgpu/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_shared {
diff --git a/amdgpu/Makefile.am b/amdgpu/Makefile.am
deleted file mode 100644
index ef8ab057..00000000
--- a/amdgpu/Makefile.am
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright © 2008 Jérôme Glisse
-#
-# 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 AUTHORS OR COPYRIGHT HOLDERS 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.
-#
-# Authors:
-# Jérôme Glisse <glisse@freedesktop.org>
-
-include Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrmdatadir = @libdrmdatadir@
-AM_CPPFLAGS = -DAMDGPU_ASIC_ID_TABLE=\"${libdrmdatadir}/amdgpu.ids\"
-
-libdrm_amdgpu_la_LTLIBRARIES = libdrm_amdgpu.la
-libdrm_amdgpu_ladir = $(libdir)
-libdrm_amdgpu_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libdrm_amdgpu_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
-
-libdrm_amdgpu_la_SOURCES = $(LIBDRM_AMDGPU_FILES)
-amdgpu_asic_id.lo: $(top_srcdir)/data/amdgpu.ids
-
-libdrm_amdgpuincludedir = ${includedir}/libdrm
-libdrm_amdgpuinclude_HEADERS = $(LIBDRM_AMDGPU_H_FILES)
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_amdgpu.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = amdgpu-symbol-check
-EXTRA_DIST = $(TESTS)
diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbols.txt
index 5ce15f46..e3bafaab 100755..100644
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbols.txt
@@ -1,17 +1,3 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.am/libdrm_amdgpuinclude_HEADERS
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_amdgpu.so} | awk '{print $3}' | while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
amdgpu_bo_alloc
amdgpu_bo_cpu_map
amdgpu_bo_cpu_unmap
@@ -46,6 +32,7 @@ amdgpu_cs_fence_to_handle
amdgpu_cs_import_syncobj
amdgpu_cs_query_fence_status
amdgpu_cs_query_reset_state
+amdgpu_cs_query_reset_state2
amdgpu_query_sw_info
amdgpu_cs_signal_semaphore
amdgpu_cs_submit
@@ -56,6 +43,7 @@ amdgpu_cs_syncobj_export_sync_file2
amdgpu_cs_syncobj_import_sync_file
amdgpu_cs_syncobj_import_sync_file2
amdgpu_cs_syncobj_query
+amdgpu_cs_syncobj_query2
amdgpu_cs_syncobj_reset
amdgpu_cs_syncobj_signal
amdgpu_cs_syncobj_timeline_signal
@@ -84,8 +72,3 @@ amdgpu_va_range_free
amdgpu_va_range_query
amdgpu_vm_reserve_vmid
amdgpu_vm_unreserve_vmid
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 66e45f73..188179c9 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -942,6 +942,21 @@ int amdgpu_cs_ctx_override_priority(amdgpu_device_handle dev,
int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
uint32_t *state, uint32_t *hangs);
+/**
+ * Query reset state for the specific GPU Context.
+ *
+ * \param context - \c [in] GPU Context handle
+ * \param flags - \c [out] A combination of AMDGPU_CTX_QUERY2_FLAGS_*
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ * \sa amdgpu_cs_ctx_create()
+ *
+*/
+int amdgpu_cs_query_reset_state2(amdgpu_context_handle context,
+ uint64_t *flags);
+
/*
* Command Buffers Management
*
@@ -1591,6 +1606,24 @@ int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
uint32_t *handles, uint64_t *points,
unsigned num_handles);
+/**
+ * Query sync objects last signaled or submitted point.
+ *
+ * \param dev - \c [in] self-explanatory
+ * \param handles - \c [in] array of sync object handles
+ * \param points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param num_handles - \c [in] self-explanatory
+ * \param flags - \c [in] a bitmask of DRM_SYNCOBJ_QUERY_FLAGS_*
+ *
+ * \return 0 on success\n
+ * -ETIME - Timeout
+ * <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev,
+ uint32_t *handles, uint64_t *points,
+ unsigned num_handles, uint32_t flags);
/**
* Export kernel sync object to shareable fd.
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 20d5aef2..fad484bf 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -28,7 +28,7 @@
#include <pthread.h>
#include <sched.h>
#include <sys/ioctl.h>
-#ifdef HAVE_ALLOCA_H
+#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
@@ -188,6 +188,25 @@ drm_public int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
return r;
}
+drm_public int amdgpu_cs_query_reset_state2(amdgpu_context_handle context,
+ uint64_t *flags)
+{
+ union drm_amdgpu_ctx args;
+ int r;
+
+ if (!context)
+ return -EINVAL;
+
+ memset(&args, 0, sizeof(args));
+ args.in.op = AMDGPU_CTX_OP_QUERY_STATE2;
+ args.in.ctx_id = context->id;
+ r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX,
+ &args, sizeof(args));
+ if (!r)
+ *flags = args.out.state.flags;
+ return r;
+}
+
/**
* Submit command to kernel DRM
* \param dev - \c [in] Device handle
@@ -201,15 +220,15 @@ drm_public int amdgpu_cs_query_reset_state(amdgpu_context_handle context,
static int amdgpu_cs_submit_one(amdgpu_context_handle context,
struct amdgpu_cs_request *ibs_request)
{
- union drm_amdgpu_cs cs;
- uint64_t *chunk_array;
struct drm_amdgpu_cs_chunk *chunks;
struct drm_amdgpu_cs_chunk_data *chunk_data;
struct drm_amdgpu_cs_chunk_dep *dependencies = NULL;
struct drm_amdgpu_cs_chunk_dep *sem_dependencies = NULL;
+ amdgpu_device_handle dev = context->dev;
struct list_head *sem_list;
amdgpu_semaphore_handle sem, tmp;
- uint32_t i, size, sem_count = 0;
+ uint32_t i, size, num_chunks, bo_list_handle = 0, sem_count = 0;
+ uint64_t seq_no;
bool user_fence;
int r = 0;
@@ -225,23 +244,18 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
size = ibs_request->number_of_ibs + (user_fence ? 2 : 1) + 1;
- chunk_array = alloca(sizeof(uint64_t) * size);
chunks = alloca(sizeof(struct drm_amdgpu_cs_chunk) * size);
size = ibs_request->number_of_ibs + (user_fence ? 1 : 0);
chunk_data = alloca(sizeof(struct drm_amdgpu_cs_chunk_data) * size);
- memset(&cs, 0, sizeof(cs));
- cs.in.chunks = (uint64_t)(uintptr_t)chunk_array;
- cs.in.ctx_id = context->id;
if (ibs_request->resources)
- cs.in.bo_list_handle = ibs_request->resources->handle;
- cs.in.num_chunks = ibs_request->number_of_ibs;
+ bo_list_handle = ibs_request->resources->handle;
+ num_chunks = ibs_request->number_of_ibs;
/* IB chunks */
for (i = 0; i < ibs_request->number_of_ibs; i++) {
struct amdgpu_cs_ib_info *ib;
- chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
chunks[i].chunk_id = AMDGPU_CHUNK_ID_IB;
chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4;
chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i];
@@ -260,10 +274,9 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
pthread_mutex_lock(&context->sequence_mutex);
if (user_fence) {
- i = cs.in.num_chunks++;
+ i = num_chunks++;
/* fence chunk */
- chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
chunks[i].chunk_id = AMDGPU_CHUNK_ID_FENCE;
chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_fence) / 4;
chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i];
@@ -276,7 +289,7 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
}
if (ibs_request->number_of_dependencies) {
- dependencies = malloc(sizeof(struct drm_amdgpu_cs_chunk_dep) *
+ dependencies = alloca(sizeof(struct drm_amdgpu_cs_chunk_dep) *
ibs_request->number_of_dependencies);
if (!dependencies) {
r = -ENOMEM;
@@ -293,10 +306,9 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
dep->handle = info->fence;
}
- i = cs.in.num_chunks++;
+ i = num_chunks++;
/* dependencies chunk */
- chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
chunks[i].chunk_id = AMDGPU_CHUNK_ID_DEPENDENCIES;
chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_dep) / 4
* ibs_request->number_of_dependencies;
@@ -307,7 +319,7 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
LIST_FOR_EACH_ENTRY(sem, sem_list, list)
sem_count++;
if (sem_count) {
- sem_dependencies = malloc(sizeof(struct drm_amdgpu_cs_chunk_dep) * sem_count);
+ sem_dependencies = alloca(sizeof(struct drm_amdgpu_cs_chunk_dep) * sem_count);
if (!sem_dependencies) {
r = -ENOMEM;
goto error_unlock;
@@ -326,26 +338,23 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
amdgpu_cs_reset_sem(sem);
amdgpu_cs_unreference_sem(sem);
}
- i = cs.in.num_chunks++;
+ i = num_chunks++;
/* dependencies chunk */
- chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i];
chunks[i].chunk_id = AMDGPU_CHUNK_ID_DEPENDENCIES;
chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_dep) / 4 * sem_count;
chunks[i].chunk_data = (uint64_t)(uintptr_t)sem_dependencies;
}
- r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CS,
- &cs, sizeof(cs));
+ r = amdgpu_cs_submit_raw2(dev, context, bo_list_handle, num_chunks,
+ chunks, &seq_no);
if (r)
goto error_unlock;
- ibs_request->seq_no = cs.out.handle;
+ ibs_request->seq_no = seq_no;
context->last_seq[ibs_request->ip_type][ibs_request->ip_instance][ibs_request->ring] = ibs_request->seq_no;
error_unlock:
pthread_mutex_unlock(&context->sequence_mutex);
- free(dependencies);
- free(sem_dependencies);
return r;
}
@@ -721,6 +730,16 @@ drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
return drmSyncobjQuery(dev->fd, handles, points, num_handles);
}
+drm_public int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev,
+ uint32_t *handles, uint64_t *points,
+ unsigned num_handles, uint32_t flags)
+{
+ if (!dev)
+ return -EINVAL;
+
+ return drmSyncobjQuery2(dev->fd, handles, points, num_handles, flags);
+}
+
drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index a340abbd..37a7c9d5 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -102,7 +102,7 @@ struct amdgpu_bo {
pthread_mutex_t cpu_access_mutex;
void *cpu_ptr;
- int cpu_map_count;
+ int64_t cpu_map_count;
};
struct amdgpu_bo_list {
diff --git a/amdgpu/meson.build b/amdgpu/meson.build
index 7c8ccc7e..d5c5f397 100644
--- a/amdgpu/meson.build
+++ b/amdgpu/meson.build
@@ -36,7 +36,7 @@ libdrm_amdgpu = shared_library(
],
include_directories : [inc_root, inc_drm],
link_with : libdrm,
- dependencies : [dep_pthread_stubs, dep_atomic_ops],
+ dependencies : [dep_pthread_stubs, dep_atomic_ops, dep_rt],
version : '1.0.0',
install : true,
)
@@ -58,8 +58,11 @@ ext_libdrm_amdgpu = declare_dependency(
)
test(
- 'amdgpu-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('amdgpu-symbol-check'), libdrm_amdgpu]
+ 'amdgpu-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_amdgpu,
+ '--symbols-file', files('amdgpu-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755
index 13d6991e..00000000
--- a/autogen.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /bin/sh
-
-srcdir=`dirname "$0"`
-test -z "$srcdir" && srcdir=.
-
-ORIGDIR=`pwd`
-cd "$srcdir"
-
-git config --local --get format.subjectPrefix >/dev/null ||
- git config --local format.subjectPrefix "PATCH libdrm" 2>/dev/null
-
-git config --local --get sendemail.to >/dev/null ||
- git config --local sendemail.to "dri-devel@lists.freedesktop.org" 2>/dev/null
-
-autoreconf --force --verbose --install || exit 1
-cd "$ORIGDIR" || exit $?
-
-if test -z "$NOCONFIGURE"; then
- "$srcdir"/configure "$@"
-fi
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index 1cf91347..00000000
--- a/configure.ac
+++ /dev/null
@@ -1,605 +0,0 @@
-# Copyright 2005 Adam Jackson.
-#
-# 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
-# on the rights to use, copy, modify, merge, publish, distribute, sub
-# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
-# ADAM JACKSON 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.
-
-AC_PREREQ([2.63])
-AC_INIT([libdrm],
- [2.4.99],
- [https://bugs.freedesktop.org/enter_bug.cgi?product=DRI],
- [libdrm])
-
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_SRCDIR([Makefile.am])
-AC_CONFIG_MACRO_DIR([m4])
-AC_CONFIG_AUX_DIR([build-aux])
-PKG_PROG_PKG_CONFIG
-
-# Require xorg-macros minimum of 1.12 for XORG_WITH_XSLTPROC
-m4_ifndef([XORG_MACROS_VERSION],
- [m4_fatal([must install xorg-macros 1.12 or later before running autoconf/autogen])])
-XORG_MACROS_VERSION(1.12)
-XORG_WITH_XSLTPROC
-XORG_MANPAGE_SECTIONS
-
-AM_INIT_AUTOMAKE([1.10 foreign dist-bzip2])
-
-# Enable quiet compiles on automake 1.11.
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-
-# Check for programs
-AC_PROG_CC
-AC_PROG_CC_C99
-AC_PROG_NM
-
-if test "x$ac_cv_prog_cc_c99" = xno; then
- AC_MSG_ERROR([Building libdrm requires C99 enabled compiler])
-fi
-
-AC_USE_SYSTEM_EXTENSIONS
-AC_SYS_LARGEFILE
-AC_FUNC_ALLOCA
-
-save_CFLAGS="$CFLAGS"
-export CFLAGS="$CFLAGS -Werror"
-AC_HEADER_MAJOR
-CFLAGS="$save_CFLAGS"
-
-AC_CHECK_HEADERS([sys/sysctl.h sys/select.h])
-
-# Initialize libtool
-LT_PREREQ([2.2])
-LT_INIT([disable-static])
-
-dnl pthread-stubs is mandatory on some BSD platforms, due to the nature of the
-dnl project. Even then there's a notable issue as described in the project README
-case "$host_os" in
-linux* | cygwin* | darwin* | solaris* | *-gnu* | gnu* | openbsd*)
- pthread_stubs_possible="no"
- ;;
-* )
- pthread_stubs_possible="yes"
- ;;
-esac
-
-if test "x$pthread_stubs_possible" = xyes; then
- PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs >= 0.4)
- AC_SUBST(PTHREADSTUBS_CFLAGS)
- AC_SUBST(PTHREADSTUBS_LIBS)
-fi
-
-pkgconfigdir=${libdir}/pkgconfig
-AC_SUBST(pkgconfigdir)
-libdrmdatadir=${datadir}/libdrm
-AC_SUBST(libdrmdatadir)
-
-AC_ARG_ENABLE([udev],
- [AS_HELP_STRING([--enable-udev],
- [Enable support for using udev instead of mknod (default: disabled)])],
- [UDEV=$enableval], [UDEV=no])
-
-AC_ARG_ENABLE(libkms,
- AS_HELP_STRING([--disable-libkms],
- [Disable KMS mm abstraction library (default: auto, enabled on supported platforms)]),
- [LIBKMS=$enableval], [LIBKMS=auto])
-
-AC_ARG_ENABLE(intel,
- AS_HELP_STRING([--disable-intel],
- [Enable support for intel's KMS API (default: auto, enabled on x86)]),
- [INTEL=$enableval], [INTEL=auto])
-
-AC_ARG_ENABLE(radeon,
- AS_HELP_STRING([--disable-radeon],
- [Enable support for radeon's KMS API (default: auto)]),
- [RADEON=$enableval], [RADEON=auto])
-
-AC_ARG_ENABLE(amdgpu,
- AS_HELP_STRING([--disable-amdgpu],
- [Enable support for amdgpu's KMS API (default: auto)]),
- [AMDGPU=$enableval], [AMDGPU=auto])
-
-AC_ARG_ENABLE(nouveau,
- AS_HELP_STRING([--disable-nouveau],
- [Enable support for nouveau's KMS API (default: auto)]),
- [NOUVEAU=$enableval], [NOUVEAU=auto])
-
-AC_ARG_ENABLE(vmwgfx,
- AS_HELP_STRING([--disable-vmwgfx],
- [Enable support for vmwgfx's KMS API (default: yes)]),
- [VMWGFX=$enableval], [VMWGFX=yes])
-
-AC_ARG_ENABLE(omap-experimental-api,
- AS_HELP_STRING([--enable-omap-experimental-api],
- [Enable support for OMAP's experimental API (default: disabled)]),
- [OMAP=$enableval], [OMAP=no])
-
-AC_ARG_ENABLE(exynos-experimental-api,
- AS_HELP_STRING([--enable-exynos-experimental-api],
- [Enable support for EXYNOS's experimental API (default: disabled)]),
- [EXYNOS=$enableval], [EXYNOS=no])
-
-AC_ARG_ENABLE(freedreno,
- AS_HELP_STRING([--disable-freedreno],
- [Enable support for freedreno's KMS API (default: auto, enabled on arm)]),
- [FREEDRENO=$enableval], [FREEDRENO=auto])
-
-AC_ARG_ENABLE(freedreno-kgsl,
- AS_HELP_STRING([--enable-freedreno-kgsl],
- [Enable support for freedreno's to use downstream android kernel API (default: disabled)]),
- [FREEDRENO_KGSL=$enableval], [FREEDRENO_KGSL=no])
-
-AC_ARG_ENABLE(tegra-experimental-api,
- AS_HELP_STRING([--enable-tegra-experimental-api],
- [Enable support for Tegra's experimental API (default: disabled)]),
- [TEGRA=$enableval], [TEGRA=no])
-
-AC_ARG_ENABLE(vc4,
- AS_HELP_STRING([--disable-vc4],
- [Enable support for vc4's API (default: auto, enabled on arm)]),
- [VC4=$enableval], [VC4=auto])
-
-AC_ARG_ENABLE(etnaviv-experimental-api,
- AS_HELP_STRING([--enable-etnaviv-experimental-api],
- [Enable support for etnaviv's experimental API (default: disabled)]),
- [ETNAVIV=$enableval], [ETNAVIV=no])
-
-AC_ARG_ENABLE(install-test-programs,
- AS_HELP_STRING([--enable-install-test-programs],
- [Install test programs (default: no)]),
- [INSTALL_TESTS=$enableval], [INSTALL_TESTS=no])
-
-dnl ===========================================================================
-dnl check compiler flags
-AC_DEFUN([LIBDRM_CC_TRY_FLAG], [
- AC_MSG_CHECKING([whether $CC supports $1])
-
- libdrm_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $1"
-
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([ ])], [libdrm_cc_flag=yes], [libdrm_cc_flag=no])
- CFLAGS="$libdrm_save_CFLAGS"
-
- if test "x$libdrm_cc_flag" = "xyes"; then
- ifelse([$2], , :, [$2])
- else
- ifelse([$3], , :, [$3])
- fi
- AC_MSG_RESULT([$libdrm_cc_flag])
-])
-
-dnl We use clock_gettime to check for timeouts in drmWaitVBlank
-
-AC_CHECK_FUNCS([clock_gettime], [CLOCK_LIB=],
- [AC_CHECK_LIB([rt], [clock_gettime], [CLOCK_LIB=-lrt],
- [AC_MSG_ERROR([Couldn't find clock_gettime])])])
-AC_SUBST([CLOCK_LIB])
-
-AC_CHECK_FUNCS([open_memstream],
- [AC_DEFINE([HAVE_OPEN_MEMSTREAM], 1, [Have open_memstream()])],
- [AC_DEFINE([HAVE_OPEN_MEMSTREAM], 0)])
-
-dnl Use lots of warning flags with with gcc and compatible compilers
-
-dnl Note: if you change the following variable, the cache is automatically
-dnl skipped and all flags rechecked. So there's no need to do anything
-dnl else. If for any reason you need to force a recheck, just change
-dnl MAYBE_WARN in an ignorable way (like adding whitespace)
-
-MAYBE_WARN="-Wall -Wextra -Werror=undef \
--Wsign-compare -Werror-implicit-function-declaration \
--Wpointer-arith -Wwrite-strings -Wstrict-prototypes \
--Wmissing-prototypes -Wmissing-declarations -Wnested-externs \
--Wpacked -Wswitch-enum -Wmissing-format-attribute \
--Wstrict-aliasing=2 -Winit-self \
--Wdeclaration-after-statement -Wold-style-definition \
--Wno-unused-parameter \
--Wno-attributes -Wno-long-long -Winline -Wshadow \
--Wno-missing-field-initializers"
-
-# invalidate cached value if MAYBE_WARN has changed
-if test "x$libdrm_cv_warn_maybe" != "x$MAYBE_WARN"; then
- unset libdrm_cv_warn_cflags
-fi
-AC_CACHE_CHECK([for supported warning flags], libdrm_cv_warn_cflags, [
- echo
- WARN_CFLAGS=""
-
- # Some warning options are not supported by all versions of
- # gcc, so test all desired options against the current
- # compiler.
- #
- # Note that there are some order dependencies
- # here. Specifically, an option that disables a warning will
- # have no net effect if a later option then enables that
- # warnings, (perhaps implicitly). So we put some grouped
- # options (-Wall and -Wextra) up front and the -Wno options
- # last.
-
- for W in $MAYBE_WARN; do
- LIBDRM_CC_TRY_FLAG([$W], [WARN_CFLAGS="$WARN_CFLAGS $W"])
- done
-
- libdrm_cv_warn_cflags=$WARN_CFLAGS
- libdrm_cv_warn_maybe=$MAYBE_WARN
-
- AC_MSG_CHECKING([which warning flags were supported])])
-WARN_CFLAGS="$libdrm_cv_warn_cflags"
-
-# Check for atomic intrinsics
-AC_CACHE_CHECK([for native atomic primitives], drm_cv_atomic_primitives, [
- drm_cv_atomic_primitives="none"
-
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- int atomic_add(int *i) { return __sync_add_and_fetch (i, 1); }
- int atomic_cmpxchg(int *i, int j, int k) { return __sync_val_compare_and_swap (i, j, k); }
- ]],[[]])], [drm_cv_atomic_primitives="Intel"],[])
-
- if test "x$drm_cv_atomic_primitives" = "xnone"; then
- AC_CHECK_HEADER([atomic_ops.h], drm_cv_atomic_primitives="libatomic-ops")
- fi
-
- # atomic functions defined in <atomic.h> & libc on Solaris
- if test "x$drm_cv_atomic_primitives" = "xnone"; then
- AC_CHECK_FUNC([atomic_cas_uint], drm_cv_atomic_primitives="Solaris")
- fi
-])
-
-if test "x$drm_cv_atomic_primitives" = xIntel; then
- AC_DEFINE(HAVE_LIBDRM_ATOMIC_PRIMITIVES, 1,
- [Enable if your compiler supports the Intel __sync_* atomic primitives])
-else
- AC_DEFINE(HAVE_LIBDRM_ATOMIC_PRIMITIVES, 0)
-fi
-if test "x$drm_cv_atomic_primitives" = "xlibatomic-ops"; then
- AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 1, [Enable if you have libatomic-ops-dev installed])
-else
- AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 0)
-fi
-
-dnl Print out the approapriate message considering the value set be the
-dnl respective in $1.
-dnl $1 - value to be evaluated. Eg. $INTEL, $NOUVEAU, ...
-dnl $2 - libdrm shortname. Eg. intel, freedreno, ...
-dnl $3 - GPU name/brand. Eg. Intel, NVIDIA Tegra, ...
-dnl $4 - Configure switch. Eg. intel, omap-experimental-api, ...
-AC_DEFUN([LIBDRM_ATOMICS_NOT_FOUND_MSG], [
- case "x$1" in
- xyes) AC_MSG_ERROR([libdrm_$2 depends upon atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package, or, failing both of those, disable support for $3 GPUs by passing --disable-$4 to ./configure]) ;;
- xauto) AC_MSG_WARN([Disabling $2. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.]) ;;
- *) ;;
- esac
-])
-
-if test "x$drm_cv_atomic_primitives" = "xnone"; then
- LIBDRM_ATOMICS_NOT_FOUND_MSG($INTEL, intel, Intel, intel)
- INTEL=no
-
- LIBDRM_ATOMICS_NOT_FOUND_MSG($RADEON, radeon, Radeon, radeon)
- RADEON=no
-
- LIBDRM_ATOMICS_NOT_FOUND_MSG($AMDGPU, amdgpu, AMD, amdgpu)
- AMDGPU=no
-
- LIBDRM_ATOMICS_NOT_FOUND_MSG($NOUVEAU, nouveau, NVIDIA, nouveau)
- NOUVEAU=no
-
- LIBDRM_ATOMICS_NOT_FOUND_MSG($OMAP, omap, OMAP, omap-experimental-api)
- OMAP=no
-
- LIBDRM_ATOMICS_NOT_FOUND_MSG($FREEDRENO, freedreno, Qualcomm Adreno, freedreno)
- FREEDRENO=no
-
- LIBDRM_ATOMICS_NOT_FOUND_MSG($TEGRA, tegra, NVIDIA Tegra, tegra-experimental-api)
- TEGRA=no
-
- LIBDRM_ATOMICS_NOT_FOUND_MSG($ETNAVIV, etnaviv, Vivante, etnaviv-experimental-api)
- ETNAVIV=no
-else
- if test "x$INTEL" = xauto; then
- case $host_cpu in
- i?86|x86_64) INTEL=yes ;;
- *) INTEL=no ;;
- esac
- fi
- if test "x$RADEON" = xauto; then
- RADEON=yes
- fi
- if test "x$AMDGPU" = xauto; then
- AMDGPU=yes
- fi
- if test "x$NOUVEAU" = xauto; then
- NOUVEAU=yes
- fi
- if test "x$FREEDRENO" = xauto; then
- case $host_cpu in
- arm*|aarch64) FREEDRENO=yes ;;
- *) FREEDRENO=no ;;
- esac
- fi
- if test "x$VC4" = xauto; then
- case $host_cpu in
- arm*|aarch64) VC4=yes ;;
- *) VC4=no ;;
- esac
- fi
-fi
-
-if test "x$INTEL" != "xno"; then
- PKG_CHECK_MODULES(PCIACCESS, [pciaccess >= 0.10])
-fi
-AC_SUBST(PCIACCESS_CFLAGS)
-AC_SUBST(PCIACCESS_LIBS)
-
-if test "x$UDEV" = xyes; then
- AC_DEFINE(UDEV, 1, [Have UDEV support])
-else
- AC_DEFINE(UDEV, 0)
-fi
-
-AC_CANONICAL_HOST
-if test "x$LIBKMS" = xauto ; then
- case $host_os in
- linux*) LIBKMS="yes" ;;
- freebsd* | kfreebsd*-gnu)
- LIBKMS="yes" ;;
- dragonfly*) LIBKMS="yes" ;;
- *) LIBKMS="no" ;;
- esac
-fi
-
-AM_CONDITIONAL(HAVE_LIBKMS, [test "x$LIBKMS" = xyes])
-
-AM_CONDITIONAL(HAVE_INTEL, [test "x$INTEL" = xyes])
-if test "x$INTEL" = xyes; then
- AC_DEFINE(HAVE_INTEL, 1, [Have intel support])
-else
- AC_DEFINE(HAVE_INTEL, 0)
-fi
-
-AM_CONDITIONAL(HAVE_VMWGFX, [test "x$VMWGFX" = xyes])
-if test "x$VMWGFX" = xyes; then
- AC_DEFINE(HAVE_VMWGFX, 1, [Have vmwgfx kernel headers])
-else
- AC_DEFINE(HAVE_VMWGFX, 0)
-fi
-
-AM_CONDITIONAL(HAVE_NOUVEAU, [test "x$NOUVEAU" = xyes])
-if test "x$NOUVEAU" = xyes; then
- AC_DEFINE(HAVE_NOUVEAU, 1, [Have nouveau (nvidia) support])
-else
- AC_DEFINE(HAVE_NOUVEAU, 0)
-fi
-
-AM_CONDITIONAL(HAVE_OMAP, [test "x$OMAP" = xyes])
-
-AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes])
-if test "x$EXYNOS" = xyes; then
- AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
-else
- AC_DEFINE(HAVE_EXYNOS, 0)
-fi
-
-AM_CONDITIONAL(HAVE_FREEDRENO, [test "x$FREEDRENO" = xyes])
-
-if test "x$FREEDRENO_KGSL" = xyes; then
- if test "x$FREEDRENO" != xyes; then
- AC_MSG_ERROR([Cannot enable freedreno KGSL interface if freedreno is disabled])
- fi
-fi
-AM_CONDITIONAL(HAVE_FREEDRENO_KGSL, [test "x$FREEDRENO_KGSL" = xyes])
-if test "x$FREEDRENO_KGSL" = xyes; then
- AC_DEFINE(HAVE_FREEDRENO_KGSL, 1, [Have freedreno support for KGSL kernel interface])
-else
- AC_DEFINE(HAVE_FREEDRENO_KGSL, 0)
-fi
-
-AM_CONDITIONAL(HAVE_RADEON, [test "x$RADEON" = xyes])
-if test "x$RADEON" = xyes; then
- AC_DEFINE(HAVE_RADEON, 1, [Have radeon support])
-else
- AC_DEFINE(HAVE_RADEON, 0)
-fi
-
-if test "x$AMDGPU" != xno; then
- # Detect cunit library
- PKG_CHECK_MODULES([CUNIT], [cunit >= 2.1], [have_cunit=yes], [have_cunit=no])
- # If pkg-config does not find cunit, check it using AC_CHECK_LIB. We
- # do this because Debian (Ubuntu) lacks pkg-config file for cunit.
- # fixed in 2.1-2.dfsg-3: http://anonscm.debian.org/cgit/collab-maint/cunit.git/commit/?h=debian
- if test "x${have_cunit}" = "xno"; then
- AC_CHECK_LIB([cunit], [CU_initialize_registry], [have_cunit=yes], [have_cunit=no])
- if test "x${have_cunit}" = "xyes"; then
- CUNIT_LIBS="-lcunit"
- CUNIT_CFLAGS=""
- AC_SUBST([CUNIT_LIBS])
- AC_SUBST([CUNIT_CFLAGS])
- fi
- fi
-else
- have_cunit=no
-fi
-AM_CONDITIONAL(HAVE_CUNIT, [test "x$have_cunit" != "xno"])
-
-AM_CONDITIONAL(HAVE_AMDGPU, [test "x$AMDGPU" = xyes])
-if test "x$AMDGPU" = xyes; then
- AC_DEFINE(HAVE_AMDGPU, 1, [Have amdgpu support])
-
- if test "x$have_cunit" = "xno"; then
- AC_MSG_WARN([Could not find cunit library. Disabling amdgpu tests])
- fi
-else
- AC_DEFINE(HAVE_AMDGPU, 0)
-fi
-
-AM_CONDITIONAL(HAVE_TEGRA, [test "x$TEGRA" = xyes])
-
-AM_CONDITIONAL(HAVE_VC4, [test "x$VC4" = xyes])
-if test "x$VC4" = xyes; then
- AC_DEFINE(HAVE_VC4, 1, [Have VC4 support])
-else
- AC_DEFINE(HAVE_VC4, 0)
-fi
-
-AM_CONDITIONAL(HAVE_ETNAVIV, [test "x$ETNAVIV" = xyes])
-
-AM_CONDITIONAL(HAVE_INSTALL_TESTS, [test "x$INSTALL_TESTS" = xyes])
-
-AC_ARG_ENABLE([cairo-tests],
- [AS_HELP_STRING([--enable-cairo-tests],
- [Enable support for Cairo rendering in tests (default: auto)])],
- [CAIRO=$enableval], [CAIRO=auto])
-if test "x$CAIRO" != xno; then
- PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no])
-fi
-AC_MSG_CHECKING([whether to enable Cairo tests])
-if test "x$CAIRO" = xauto; then
- CAIRO="$HAVE_CAIRO"
-fi
-if test "x$CAIRO" = xyes; then
- if ! test "x$HAVE_CAIRO" = xyes; then
- AC_MSG_ERROR([Cairo support required but not present])
- fi
- AC_DEFINE(HAVE_CAIRO, 1, [Have Cairo support])
-else
- AC_DEFINE(HAVE_CAIRO, 0)
-fi
-AC_MSG_RESULT([$CAIRO])
-AM_CONDITIONAL(HAVE_CAIRO, [test "x$CAIRO" = xyes])
-
-# xsltproc for docbook manpages
-AC_ARG_ENABLE([manpages],
- AS_HELP_STRING([--enable-manpages], [enable manpages @<:@default=auto@:>@]),
- [MANS=$enableval], [MANS=auto])
-AM_CONDITIONAL([BUILD_MANPAGES], [test "x$XSLTPROC" != "x" -a "x$MANS" != "xno"])
-
-# check for offline man-pages stylesheet
-AC_MSG_CHECKING([for docbook manpages stylesheet])
-MANPAGES_STYLESHEET="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"
-AC_PATH_PROGS_FEATURE_CHECK([XSLTPROC_TMP], [xsltproc],
- AS_IF([`"$ac_path_XSLTPROC_TMP" --nonet "$MANPAGES_STYLESHEET" > /dev/null 2>&1`],
- [HAVE_MANPAGES_STYLESHEET=yes]))
-if test "x$HAVE_MANPAGES_STYLESHEET" = "xyes"; then
- AC_SUBST(MANPAGES_STYLESHEET)
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-AM_CONDITIONAL([HAVE_MANPAGES_STYLESHEET], [test "x$HAVE_MANPAGES_STYLESHEET" = "xyes"])
-
-AC_ARG_ENABLE(valgrind,
- [AS_HELP_STRING([--enable-valgrind],
- [Build libdrm with valgrind support (default: auto)])],
- [VALGRIND=$enableval], [VALGRIND=auto])
-if test "x$VALGRIND" != xno; then
- PKG_CHECK_MODULES(VALGRIND, [valgrind], [have_valgrind=yes], [have_valgrind=no])
-fi
-AC_MSG_CHECKING([whether to enable Valgrind support])
-if test "x$VALGRIND" = xauto; then
- VALGRIND="$have_valgrind"
-fi
-
-if test "x$VALGRIND" = "xyes"; then
- if ! test "x$have_valgrind" = xyes; then
- AC_MSG_ERROR([Valgrind support required but not present])
- fi
- AC_DEFINE([HAVE_VALGRIND], 1, [Use valgrind intrinsics to suppress false warnings])
-else
- AC_DEFINE([HAVE_VALGRIND], 0)
-fi
-
-AC_MSG_RESULT([$VALGRIND])
-
-AC_ARG_WITH([kernel-source],
- [AS_HELP_STRING([--with-kernel-source],
- [specify path to linux kernel source])],
- [kernel_source="$with_kernel_source"])
-AC_SUBST(kernel_source)
-
-AC_MSG_CHECKING([whether $CC supports __attribute__(("hidden"))])
-AC_LINK_IFELSE([AC_LANG_PROGRAM([
- int foo_hidden( void ) __attribute__((visibility("hidden")));
-])], HAVE_ATTRIBUTE_VISIBILITY="yes"; AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]));
-
-if test "x$HAVE_ATTRIBUTE_VISIBILITY" = xyes; then
- AC_DEFINE(HAVE_VISIBILITY, 1, [Compiler supports __attribute__(("hidden"))])
-else
- AC_DEFINE(HAVE_VISIBILITY, 0)
-fi
-
-CPPFLAGS="$CPPFLAGS -include config.h"
-
-AC_SUBST(WARN_CFLAGS)
-AC_CONFIG_FILES([
- Makefile
- data/Makefile
- libkms/Makefile
- libkms/libkms.pc
- intel/Makefile
- intel/libdrm_intel.pc
- radeon/Makefile
- radeon/libdrm_radeon.pc
- amdgpu/Makefile
- amdgpu/libdrm_amdgpu.pc
- nouveau/Makefile
- nouveau/libdrm_nouveau.pc
- omap/Makefile
- omap/libdrm_omap.pc
- exynos/Makefile
- exynos/libdrm_exynos.pc
- freedreno/Makefile
- freedreno/libdrm_freedreno.pc
- tegra/Makefile
- tegra/libdrm_tegra.pc
- vc4/Makefile
- vc4/libdrm_vc4.pc
- etnaviv/Makefile
- etnaviv/libdrm_etnaviv.pc
- tests/Makefile
- tests/modeprint/Makefile
- tests/modetest/Makefile
- tests/kms/Makefile
- tests/kmstest/Makefile
- tests/proptest/Makefile
- tests/radeon/Makefile
- tests/amdgpu/Makefile
- tests/vbltest/Makefile
- tests/exynos/Makefile
- tests/tegra/Makefile
- tests/nouveau/Makefile
- tests/etnaviv/Makefile
- tests/util/Makefile
- man/Makefile
- libdrm.pc])
-AC_OUTPUT
-
-echo ""
-echo "$PACKAGE_STRING will be compiled with:"
-echo ""
-echo " libkms $LIBKMS"
-echo " Intel API $INTEL"
-echo " vmwgfx API $VMWGFX"
-echo " Radeon API $RADEON"
-echo " AMDGPU API $AMDGPU"
-echo " Nouveau API $NOUVEAU"
-echo " OMAP API $OMAP"
-echo " EXYNOS API $EXYNOS"
-echo " Freedreno API $FREEDRENO (kgsl: $FREEDRENO_KGSL)"
-echo " Tegra API $TEGRA"
-echo " VC4 API $VC4"
-echo " Etnaviv API $ETNAVIV"
-echo ""
diff --git a/core-symbols.txt b/core-symbols.txt
new file mode 100644
index 00000000..410054b3
--- /dev/null
+++ b/core-symbols.txt
@@ -0,0 +1,198 @@
+drmAddBufs
+drmAddContextPrivateMapping
+drmAddContextTag
+drmAddMap
+drmAgpAcquire
+drmAgpAlloc
+drmAgpBase
+drmAgpBind
+drmAgpDeviceId
+drmAgpEnable
+drmAgpFree
+drmAgpGetMode
+drmAgpMemoryAvail
+drmAgpMemoryUsed
+drmAgpRelease
+drmAgpSize
+drmAgpUnbind
+drmAgpVendorId
+drmAgpVersionMajor
+drmAgpVersionMinor
+drmAuthMagic
+drmAvailable
+drmCheckModesettingSupported
+drmClose
+drmCloseOnce
+drmCommandNone
+drmCommandRead
+drmCommandWrite
+drmCommandWriteRead
+drmCreateContext
+drmCreateDrawable
+drmCrtcGetSequence
+drmCrtcQueueSequence
+drmCtlInstHandler
+drmCtlUninstHandler
+drmDelContextTag
+drmDestroyContext
+drmDestroyDrawable
+drmDevicesEqual
+drmDMA
+drmDropMaster
+drmError
+drmFinish
+drmFree
+drmFreeBufs
+drmFreeBusid
+drmFreeDevice
+drmFreeDevices
+drmFreeReservedContextList
+drmFreeVersion
+drmGetBufInfo
+drmGetBusid
+drmGetCap
+drmGetClient
+drmGetContextFlags
+drmGetContextPrivateMapping
+drmGetContextTag
+drmGetDevice
+drmGetDevice2
+drmGetDeviceNameFromFd
+drmGetDeviceNameFromFd2
+drmGetDevices
+drmGetDevices2
+drmGetEntry
+drmGetHashTable
+drmGetInterruptFromBusID
+drmGetLibVersion
+drmGetLock
+drmGetMagic
+drmGetMap
+drmGetNodeTypeFromFd
+drmGetPrimaryDeviceNameFromFd
+drmGetRenderDeviceNameFromFd
+drmGetReservedContextList
+drmGetStats
+drmGetVersion
+drmHandleEvent
+drmHashCreate
+drmHashDelete
+drmHashDestroy
+drmHashFirst
+drmHashInsert
+drmHashLookup
+drmHashNext
+drmIoctl
+drmIsKMS
+drmIsMaster
+drmMalloc
+drmMap
+drmMapBufs
+drmMarkBufs
+drmModeAddFB
+drmModeAddFB2
+drmModeAddFB2WithModifiers
+drmModeAtomicAddProperty
+drmModeAtomicAlloc
+drmModeAtomicCommit
+drmModeAtomicDuplicate
+drmModeAtomicFree
+drmModeAtomicGetCursor
+drmModeAtomicMerge
+drmModeAtomicSetCursor
+drmModeAttachMode
+drmModeConnectorSetProperty
+drmModeCreateLease
+drmModeCreatePropertyBlob
+drmModeCrtcGetGamma
+drmModeCrtcSetGamma
+drmModeDestroyPropertyBlob
+drmModeDetachMode
+drmModeDirtyFB
+drmModeFreeConnector
+drmModeFreeCrtc
+drmModeFreeEncoder
+drmModeFreeFB
+drmModeFreeFB2
+drmModeFreeModeInfo
+drmModeFreeObjectProperties
+drmModeFreePlane
+drmModeFreePlaneResources
+drmModeFreeProperty
+drmModeFreePropertyBlob
+drmModeFreeResources
+drmModeGetConnector
+drmModeGetConnectorCurrent
+drmModeGetCrtc
+drmModeGetEncoder
+drmModeGetFB
+drmModeGetFB2
+drmModeGetLease
+drmModeGetPlane
+drmModeGetPlaneResources
+drmModeGetProperty
+drmModeGetPropertyBlob
+drmModeGetResources
+drmModeListLessees
+drmModeMoveCursor
+drmModeObjectGetProperties
+drmModeObjectSetProperty
+drmModePageFlip
+drmModePageFlipTarget
+drmModeRevokeLease
+drmModeRmFB
+drmModeSetCrtc
+drmModeSetCursor
+drmModeSetCursor2
+drmModeSetPlane
+drmMsg
+drmOpen
+drmOpenControl
+drmOpenOnce
+drmOpenOnceWithType
+drmOpenRender
+drmOpenWithType
+drmPrimeFDToHandle
+drmPrimeHandleToFD
+drmRandom
+drmRandomCreate
+drmRandomDestroy
+drmRandomDouble
+drmRmMap
+drmScatterGatherAlloc
+drmScatterGatherFree
+drmSetBusid
+drmSetClientCap
+drmSetContextFlags
+drmSetInterfaceVersion
+drmSetMaster
+drmSetServerInfo
+drmSLCreate
+drmSLDelete
+drmSLDestroy
+drmSLDump
+drmSLFirst
+drmSLInsert
+drmSLLookup
+drmSLLookupNeighbors
+drmSLNext
+drmSwitchToContext
+drmSyncobjCreate
+drmSyncobjDestroy
+drmSyncobjExportSyncFile
+drmSyncobjFDToHandle
+drmSyncobjHandleToFD
+drmSyncobjImportSyncFile
+drmSyncobjQuery
+drmSyncobjQuery2
+drmSyncobjReset
+drmSyncobjSignal
+drmSyncobjTimelineSignal
+drmSyncobjTimelineWait
+drmSyncobjTransfer
+drmSyncobjWait
+drmUnlock
+drmUnmap
+drmUnmapBufs
+drmUpdateDrawableInfo
+drmWaitVBlank
diff --git a/data/Android.bp b/data/Android.bp
index 47f64371..8bb59211 100644
--- a/data/Android.bp
+++ b/data/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
prebuilt_etc {
name: "amdgpu.ids",
proprietary: true,
diff --git a/data/Makefile.am b/data/Makefile.am
deleted file mode 100644
index 897a7f35..00000000
--- a/data/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright © 2017 Advanced Micro Devices, 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
-# on the rights to use, copy, modify, merge, publish, distribute, sub
-# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
-# ADAM JACKSON 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.
-
-libdrmdatadir = @libdrmdatadir@
-if HAVE_AMDGPU
-dist_libdrmdata_DATA = amdgpu.ids
-endif
diff --git a/data/amdgpu.ids b/data/amdgpu.ids
index f61497e4..93c1c763 100644
--- a/data/amdgpu.ids
+++ b/data/amdgpu.ids
@@ -4,10 +4,67 @@
# device_id, revision_id, product_name <-- single tab after comma
1.0.0
+15DD, C3, AMD Radeon(TM) Vega 3 Graphics
+15DD, CB, AMD Radeon(TM) Vega 3 Graphics
+15DD, CE, AMD Radeon(TM) Vega 3 Graphics
+15DD, D8, AMD Radeon(TM) Vega 3 Graphics
+15DD, CC, AMD Radeon(TM) Vega 6 Graphics
+15DD, D9, AMD Radeon(TM) Vega 6 Graphics
+15DD, C2, AMD Radeon(TM) Vega 8 Graphics
+15DD, C4, AMD Radeon(TM) Vega 8 Graphics
+15DD, C8, AMD Radeon(TM) Vega 8 Graphics
+15DD, CA, AMD Radeon(TM) Vega 8 Graphics
+15DD, D1, AMD Radeon(TM) Vega 8 Graphics
+15DD, D5, AMD Radeon(TM) Vega 8 Graphics
+15DD, D7, AMD Radeon(TM) Vega 8 Graphics
+15DD, C3, AMD Radeon(TM) Vega 10 Graphics
+15DD, D0, AMD Radeon(TM) Vega 10 Graphics
+15DD, C1, AMD Radeon(TM) Vega 11 Graphics
+15DD, C6, AMD Radeon(TM) Vega 11 Graphics
+15DD, C9, AMD Radeon(TM) Vega 11 Graphics
+15DD, D3, AMD Radeon(TM) Vega 11 Graphics
+15DD, D6, AMD Radeon(TM) Vega 11 Graphics
15DD, 81, AMD Ryzen Embedded V1807B with Radeon Vega Gfx
15DD, 82, AMD Ryzen Embedded V1756B with Radeon Vega Gfx
15DD, 83, AMD Ryzen Embedded V1605B with Radeon Vega Gfx
15DD, 85, AMD Ryzen Embedded V1202B with Radeon Vega Gfx
+15D8, 93, AMD Radeon(TM) Vega 1 Graphics
+15D8, C4, AMD Radeon(TM) Vega 3 Graphics
+15D8, C5, AMD Radeon(TM) Vega 3 Graphics
+15D8, CC, AMD Radeon(TM) Vega 3 Graphics
+15D8, CE, AMD Radeon(TM) Vega 3 Graphics
+15D8, CF, AMD Radeon(TM) Vega 3 Graphics
+15D8, D4, AMD Radeon(TM) Vega 3 Graphics
+15D8, DC, AMD Radeon(TM) Vega 3 Graphics
+15D8, DD, AMD Radeon(TM) Vega 3 Graphics
+15D8, DE, AMD Radeon(TM) Vega 3 Graphics
+15D8, DF, AMD Radeon(TM) Vega 3 Graphics
+15D8, E3, AMD Radeon(TM) Vega 3 Graphics
+15D8, E4, AMD Radeon(TM) Vega 3 Graphics
+15D8, A3, AMD Radeon(TM) Vega 6 Graphics
+15D8, B3, AMD Radeon(TM) Vega 6 Graphics
+15D8, C3, AMD Radeon(TM) Vega 6 Graphics
+15D8, D3, AMD Radeon(TM) Vega 6 Graphics
+15D8, A2, AMD Radeon(TM) Vega 8 Graphics
+15D8, B2, AMD Radeon(TM) Vega 8 Graphics
+15D8, C2, AMD Radeon(TM) Vega 8 Graphics
+15D8, C9, AMD Radeon(TM) Vega 8 Graphics
+15D8, CB, AMD Radeon(TM) Vega 8 Graphics
+15D8, D2, AMD Radeon(TM) Vega 8 Graphics
+15D8, D9, AMD Radeon(TM) Vega 8 Graphics
+15D8, DB, AMD Radeon(TM) Vega 8 Graphics
+15D8, A1, AMD Radeon(TM) Vega 10 Graphics
+15D8, B1, AMD Radeon(TM) Vega 10 Graphics
+15D8, C1, AMD Radeon(TM) Vega 10 Graphics
+15D8, D1, AMD Radeon(TM) Vega 10 Graphics
+15D8, C8, AMD Radeon(TM) Vega 11 Graphics
+15D8, CA, AMD Radeon(TM) Vega 11 Graphics
+15D8, D8, AMD Radeon(TM) Vega 11 Graphics
+15D8, DA, AMD Radeon(TM) Vega 11 Graphics
+15D8, 91, AMD Ryzen Embedded R1606G with Radeon Vega Gfx
+15D8, 92, AMD Ryzen Embedded R1505G with Radeon Vega Gfx
+15D8, CF, AMD Ryzen Embedded R1305G with Radeon Vega Gfx
+15D8, E4, AMD Ryzen Embedded R1102G with Radeon Vega Gfx
6600, 0, AMD Radeon HD 8600/8700M
6600, 81, AMD Radeon (TM) R7 M370
6601, 0, AMD Radeon (TM) HD 8500M/8700M
@@ -45,6 +102,7 @@
6665, 83, AMD Radeon (TM) R5 M320
6667, 0, AMD Radeon R5 M200 Series
666F, 0, AMD Radeon HD 8500M
+66A1, 06, AMD Radeon (TM) Pro VII
66AF, C1, AMD Radeon VII
6780, 0, ATI FirePro V (FireGL V) Graphics Adapter
678A, 0, ATI FirePro V (FireGL V) Graphics Adapter
@@ -140,6 +198,7 @@
6860, 02, Radeon Instinct MI25
6860, 03, Radeon Pro V340
6860, 04, Radeon Instinct MI25x2
+6860, 07, Radeon (TM) Pro V320
6861, 00, Radeon Pro WX 9100
6862, 00, Radeon Pro SSG
6863, 00, Radeon Vega Frontier Edition
@@ -174,9 +233,13 @@
6939, 0, AMD Radeon R9 200 Series
6939, F1, AMD Radeon (TM) R9 380 Series
6980, 00, Radeon Pro WX3100
+6981, 00, AMD Radeon (TM) Pro WX 3200 Series
+6981, 01, AMD Radeon (TM) Pro WX 3200 Series
+6981, 10, AMD Radeon (TM) Pro WX 3200 Series
6985, 00, AMD Radeon Pro WX3100
6987, 80, AMD Embedded Radeon E9171
6987, C0, Radeon 550X Series
+6987, C1, AMD Radeon RX 640
6987, C3, Radeon 540X Series
6995, 00, AMD Radeon Pro WX2100
6997, 00, Radeon Pro WX2100
@@ -184,12 +247,33 @@
699F, C0, Radeon 500 Series
699F, C1, Radeon 540 Series
699F, C3, Radeon 500 Series
-699F, C7, Radeon 550 Series
+699F, C7, Radeon RX550/550 Series
7300, C1, AMD FirePro (TM) S9300 x2
7300, C8, AMD Radeon (TM) R9 Fury Series
7300, C9, Radeon (TM) Pro Duo
7300, CB, AMD Radeon (TM) R9 Fury Series
7300, CA, AMD Radeon (TM) R9 Fury Series
+7312, 00, AMD Radeon Pro W5700
+731E, C6, AMD Radeon RX 5700XTB
+731E, C7, AMD Radeon RX 5700B
+731F, C0, AMD Radeon RX 5700 XT 50th Anniversary
+731F, C1, AMD Radeon RX 5700 XT
+731F, C2, AMD Radeon RX 5600M
+731F, C3, AMD Radeon RX 5700M
+731F, C4, AMD Radeon RX 5700
+731F, C5, AMD Radeon RX 5700 XT
+731F, CA, AMD Radeon RX 5600 XT
+731F, CB, AMD Radeon RX 5600 OEM
+7340, C1, Radeon RX 5500M
+7340, C5, Radeon RX 5500 XT
+7340, C7, Radeon RX 5500
+7340, C9, AMD Radeon RX 5500XTB
+7340, CF, Radeon RX 5300
+7341, 00, AMD Radeon Pro W5500
+7347, 00, AMD Radeon Pro W5500M
+73BF, C0, AMD Radeon RX 6900 XT
+73BF, C1, AMD Radeon RX 6800 XT
+73BF, C3, AMD Radeon RX 6800
9874, C4, AMD Radeon R7 Graphics
9874, C5, AMD Radeon R6 Graphics
9874, C6, AMD Radeon R6 Graphics
@@ -199,4 +283,5 @@
9874, 87, AMD Radeon R5 Graphics
9874, 85, AMD Radeon R6 Graphics
9874, 84, AMD Radeon R7 Graphics
+6FDF, E7, AMD Radeon RX 590 GME
6FDF, EF, AMD Radeon RX 580 2048SP
diff --git a/etnaviv/Android.bp b/etnaviv/Android.bp
index 21deda99..d8d04af1 100644
--- a/etnaviv/Android.bp
+++ b/etnaviv/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_shared {
diff --git a/etnaviv/Makefile.am b/etnaviv/Makefile.am
deleted file mode 100644
index 648e3c5b..00000000
--- a/etnaviv/Makefile.am
+++ /dev/null
@@ -1,28 +0,0 @@
-include Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_etnaviv_ladir = $(libdir)
-libdrm_etnaviv_la_LTLIBRARIES = libdrm_etnaviv.la
-libdrm_etnaviv_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libdrm_etnaviv_la_LIBADD = \
- ../libdrm.la \
- @PTHREADSTUBS_LIBS@ \
- @CLOCK_LIB@
-
-libdrm_etnaviv_la_SOURCES = $(LIBDRM_ETNAVIV_FILES)
-
-libdrm_etnavivincludedir = ${includedir}/libdrm
-libdrm_etnavivinclude_HEADERS = $(LIBDRM_ETNAVIV_H_FILES)
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_etnaviv.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = etnaviv-symbol-check
-EXTRA_DIST = $(TESTS)
diff --git a/etnaviv/Makefile.sources b/etnaviv/Makefile.sources
index 0eb73783..3ff2fbe5 100644
--- a/etnaviv/Makefile.sources
+++ b/etnaviv/Makefile.sources
@@ -6,7 +6,6 @@ LIBDRM_ETNAVIV_FILES := \
etnaviv_perfmon.c \
etnaviv_pipe.c \
etnaviv_cmd_stream.c \
- etnaviv_drm.h \
etnaviv_priv.h
LIBDRM_ETNAVIV_H_FILES := \
diff --git a/etnaviv/etnaviv-symbol-check b/etnaviv/etnaviv-symbols.txt
index 6f6a7a28..f48cecea 100755..100644
--- a/etnaviv/etnaviv-symbol-check
+++ b/etnaviv/etnaviv-symbols.txt
@@ -1,17 +1,3 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.sources/LIBDRM_ETNAVIV_H_FILES
-
-FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_etnaviv.so} | awk '{print $3}'| while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
etna_device_new
etna_device_new_dup
etna_device_ref
@@ -48,8 +34,3 @@ etna_perfmon_create
etna_perfmon_del
etna_perfmon_get_dom_by_name
etna_perfmon_get_sig_by_name
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/etnaviv/etnaviv_drm.h b/etnaviv/etnaviv_drm.h
deleted file mode 100644
index 0d5c49dc..00000000
--- a/etnaviv/etnaviv_drm.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Copyright (C) 2015 Etnaviv Project
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __ETNAVIV_DRM_H__
-#define __ETNAVIV_DRM_H__
-
-#include "drm.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/* Please note that modifications to all structs defined here are
- * subject to backwards-compatibility constraints:
- * 1) Do not use pointers, use __u64 instead for 32 bit / 64 bit
- * user/kernel compatibility
- * 2) Keep fields aligned to their size
- * 3) Because of how drm_ioctl() works, we can add new fields at
- * the end of an ioctl if some care is taken: drm_ioctl() will
- * zero out the new fields at the tail of the ioctl, so a zero
- * value should have a backwards compatible meaning. And for
- * output params, userspace won't see the newly added output
- * fields.. so that has to be somehow ok.
- */
-
-/* timeouts are specified in clock-monotonic absolute times (to simplify
- * restarting interrupted ioctls). The following struct is logically the
- * same as 'struct timespec' but 32/64b ABI safe.
- */
-struct drm_etnaviv_timespec {
- __s64 tv_sec; /* seconds */
- __s64 tv_nsec; /* nanoseconds */
-};
-
-#define ETNAVIV_PARAM_GPU_MODEL 0x01
-#define ETNAVIV_PARAM_GPU_REVISION 0x02
-#define ETNAVIV_PARAM_GPU_FEATURES_0 0x03
-#define ETNAVIV_PARAM_GPU_FEATURES_1 0x04
-#define ETNAVIV_PARAM_GPU_FEATURES_2 0x05
-#define ETNAVIV_PARAM_GPU_FEATURES_3 0x06
-#define ETNAVIV_PARAM_GPU_FEATURES_4 0x07
-#define ETNAVIV_PARAM_GPU_FEATURES_5 0x08
-#define ETNAVIV_PARAM_GPU_FEATURES_6 0x09
-#define ETNAVIV_PARAM_GPU_FEATURES_7 0x0a
-#define ETNAVIV_PARAM_GPU_FEATURES_8 0x0b
-#define ETNAVIV_PARAM_GPU_FEATURES_9 0x0c
-#define ETNAVIV_PARAM_GPU_FEATURES_10 0x0d
-#define ETNAVIV_PARAM_GPU_FEATURES_11 0x0e
-#define ETNAVIV_PARAM_GPU_FEATURES_12 0x0f
-
-#define ETNAVIV_PARAM_GPU_STREAM_COUNT 0x10
-#define ETNAVIV_PARAM_GPU_REGISTER_MAX 0x11
-#define ETNAVIV_PARAM_GPU_THREAD_COUNT 0x12
-#define ETNAVIV_PARAM_GPU_VERTEX_CACHE_SIZE 0x13
-#define ETNAVIV_PARAM_GPU_SHADER_CORE_COUNT 0x14
-#define ETNAVIV_PARAM_GPU_PIXEL_PIPES 0x15
-#define ETNAVIV_PARAM_GPU_VERTEX_OUTPUT_BUFFER_SIZE 0x16
-#define ETNAVIV_PARAM_GPU_BUFFER_SIZE 0x17
-#define ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT 0x18
-#define ETNAVIV_PARAM_GPU_NUM_CONSTANTS 0x19
-#define ETNAVIV_PARAM_GPU_NUM_VARYINGS 0x1a
-
-#define ETNA_MAX_PIPES 4
-
-struct drm_etnaviv_param {
- __u32 pipe; /* in */
- __u32 param; /* in, ETNAVIV_PARAM_x */
- __u64 value; /* out (get_param) or in (set_param) */
-};
-
-/*
- * GEM buffers:
- */
-
-#define ETNA_BO_CACHE_MASK 0x000f0000
-/* cache modes */
-#define ETNA_BO_CACHED 0x00010000
-#define ETNA_BO_WC 0x00020000
-#define ETNA_BO_UNCACHED 0x00040000
-/* map flags */
-#define ETNA_BO_FORCE_MMU 0x00100000
-
-struct drm_etnaviv_gem_new {
- __u64 size; /* in */
- __u32 flags; /* in, mask of ETNA_BO_x */
- __u32 handle; /* out */
-};
-
-struct drm_etnaviv_gem_info {
- __u32 handle; /* in */
- __u32 pad;
- __u64 offset; /* out, offset to pass to mmap() */
-};
-
-#define ETNA_PREP_READ 0x01
-#define ETNA_PREP_WRITE 0x02
-#define ETNA_PREP_NOSYNC 0x04
-
-struct drm_etnaviv_gem_cpu_prep {
- __u32 handle; /* in */
- __u32 op; /* in, mask of ETNA_PREP_x */
- struct drm_etnaviv_timespec timeout; /* in */
-};
-
-struct drm_etnaviv_gem_cpu_fini {
- __u32 handle; /* in */
- __u32 flags; /* in, placeholder for now, no defined values */
-};
-
-/*
- * Cmdstream Submission:
- */
-
-/* The value written into the cmdstream is logically:
- * relocbuf->gpuaddr + reloc_offset
- *
- * NOTE that reloc's must be sorted by order of increasing submit_offset,
- * otherwise EINVAL.
- */
-struct drm_etnaviv_gem_submit_reloc {
- __u32 submit_offset; /* in, offset from submit_bo */
- __u32 reloc_idx; /* in, index of reloc_bo buffer */
- __u64 reloc_offset; /* in, offset from start of reloc_bo */
- __u32 flags; /* in, placeholder for now, no defined values */
-};
-
-/* Each buffer referenced elsewhere in the cmdstream submit (ie. the
- * cmdstream buffer(s) themselves or reloc entries) has one (and only
- * one) entry in the submit->bos[] table.
- *
- * As a optimization, the current buffer (gpu virtual address) can be
- * passed back through the 'presumed' field. If on a subsequent reloc,
- * userspace passes back a 'presumed' address that is still valid,
- * then patching the cmdstream for this entry is skipped. This can
- * avoid kernel needing to map/access the cmdstream bo in the common
- * case.
- */
-#define ETNA_SUBMIT_BO_READ 0x0001
-#define ETNA_SUBMIT_BO_WRITE 0x0002
-struct drm_etnaviv_gem_submit_bo {
- __u32 flags; /* in, mask of ETNA_SUBMIT_BO_x */
- __u32 handle; /* in, GEM handle */
- __u64 presumed; /* in/out, presumed buffer address */
-};
-
-/* performance monitor request (pmr) */
-#define ETNA_PM_PROCESS_PRE 0x0001
-#define ETNA_PM_PROCESS_POST 0x0002
-struct drm_etnaviv_gem_submit_pmr {
- __u32 flags; /* in, when to process request (ETNA_PM_PROCESS_x) */
- __u8 domain; /* in, pm domain */
- __u8 pad;
- __u16 signal; /* in, pm signal */
- __u32 sequence; /* in, sequence number */
- __u32 read_offset; /* in, offset from read_bo */
- __u32 read_idx; /* in, index of read_bo buffer */
-};
-
-/* Each cmdstream submit consists of a table of buffers involved, and
- * one or more cmdstream buffers. This allows for conditional execution
- * (context-restore), and IB buffers needed for per tile/bin draw cmds.
- */
-#define ETNA_SUBMIT_NO_IMPLICIT 0x0001
-#define ETNA_SUBMIT_FENCE_FD_IN 0x0002
-#define ETNA_SUBMIT_FENCE_FD_OUT 0x0004
-#define ETNA_SUBMIT_FLAGS (ETNA_SUBMIT_NO_IMPLICIT | \
- ETNA_SUBMIT_FENCE_FD_IN | \
- ETNA_SUBMIT_FENCE_FD_OUT)
-#define ETNA_PIPE_3D 0x00
-#define ETNA_PIPE_2D 0x01
-#define ETNA_PIPE_VG 0x02
-struct drm_etnaviv_gem_submit {
- __u32 fence; /* out */
- __u32 pipe; /* in */
- __u32 exec_state; /* in, initial execution state (ETNA_PIPE_x) */
- __u32 nr_bos; /* in, number of submit_bo's */
- __u32 nr_relocs; /* in, number of submit_reloc's */
- __u32 stream_size; /* in, cmdstream size */
- __u64 bos; /* in, ptr to array of submit_bo's */
- __u64 relocs; /* in, ptr to array of submit_reloc's */
- __u64 stream; /* in, ptr to cmdstream */
- __u32 flags; /* in, mask of ETNA_SUBMIT_x */
- __s32 fence_fd; /* in/out, fence fd (see ETNA_SUBMIT_FENCE_FD_x) */
- __u64 pmrs; /* in, ptr to array of submit_pmr's */
- __u32 nr_pmrs; /* in, number of submit_pmr's */
- __u32 pad;
-};
-
-/* The normal way to synchronize with the GPU is just to CPU_PREP on
- * a buffer if you need to access it from the CPU (other cmdstream
- * submission from same or other contexts, PAGE_FLIP ioctl, etc, all
- * handle the required synchronization under the hood). This ioctl
- * mainly just exists as a way to implement the gallium pipe_fence
- * APIs without requiring a dummy bo to synchronize on.
- */
-#define ETNA_WAIT_NONBLOCK 0x01
-struct drm_etnaviv_wait_fence {
- __u32 pipe; /* in */
- __u32 fence; /* in */
- __u32 flags; /* in, mask of ETNA_WAIT_x */
- __u32 pad;
- struct drm_etnaviv_timespec timeout; /* in */
-};
-
-#define ETNA_USERPTR_READ 0x01
-#define ETNA_USERPTR_WRITE 0x02
-struct drm_etnaviv_gem_userptr {
- __u64 user_ptr; /* in, page aligned user pointer */
- __u64 user_size; /* in, page aligned user size */
- __u32 flags; /* in, flags */
- __u32 handle; /* out, non-zero handle */
-};
-
-struct drm_etnaviv_gem_wait {
- __u32 pipe; /* in */
- __u32 handle; /* in, bo to be waited for */
- __u32 flags; /* in, mask of ETNA_WAIT_x */
- __u32 pad;
- struct drm_etnaviv_timespec timeout; /* in */
-};
-
-/*
- * Performance Monitor (PM):
- */
-
-struct drm_etnaviv_pm_domain {
- __u32 pipe; /* in */
- __u8 iter; /* in/out, select pm domain at index iter */
- __u8 id; /* out, id of domain */
- __u16 nr_signals; /* out, how many signals does this domain provide */
- char name[64]; /* out, name of domain */
-};
-
-struct drm_etnaviv_pm_signal {
- __u32 pipe; /* in */
- __u8 domain; /* in, pm domain index */
- __u8 pad;
- __u16 iter; /* in/out, select pm source at index iter */
- __u16 id; /* out, id of signal */
- char name[64]; /* out, name of domain */
-};
-
-#define DRM_ETNAVIV_GET_PARAM 0x00
-/* placeholder:
-#define DRM_ETNAVIV_SET_PARAM 0x01
- */
-#define DRM_ETNAVIV_GEM_NEW 0x02
-#define DRM_ETNAVIV_GEM_INFO 0x03
-#define DRM_ETNAVIV_GEM_CPU_PREP 0x04
-#define DRM_ETNAVIV_GEM_CPU_FINI 0x05
-#define DRM_ETNAVIV_GEM_SUBMIT 0x06
-#define DRM_ETNAVIV_WAIT_FENCE 0x07
-#define DRM_ETNAVIV_GEM_USERPTR 0x08
-#define DRM_ETNAVIV_GEM_WAIT 0x09
-#define DRM_ETNAVIV_PM_QUERY_DOM 0x0a
-#define DRM_ETNAVIV_PM_QUERY_SIG 0x0b
-#define DRM_ETNAVIV_NUM_IOCTLS 0x0c
-
-#define DRM_IOCTL_ETNAVIV_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GET_PARAM, struct drm_etnaviv_param)
-#define DRM_IOCTL_ETNAVIV_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_NEW, struct drm_etnaviv_gem_new)
-#define DRM_IOCTL_ETNAVIV_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_INFO, struct drm_etnaviv_gem_info)
-#define DRM_IOCTL_ETNAVIV_GEM_CPU_PREP DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_CPU_PREP, struct drm_etnaviv_gem_cpu_prep)
-#define DRM_IOCTL_ETNAVIV_GEM_CPU_FINI DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_CPU_FINI, struct drm_etnaviv_gem_cpu_fini)
-#define DRM_IOCTL_ETNAVIV_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_SUBMIT, struct drm_etnaviv_gem_submit)
-#define DRM_IOCTL_ETNAVIV_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_WAIT_FENCE, struct drm_etnaviv_wait_fence)
-#define DRM_IOCTL_ETNAVIV_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_USERPTR, struct drm_etnaviv_gem_userptr)
-#define DRM_IOCTL_ETNAVIV_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_WAIT, struct drm_etnaviv_gem_wait)
-#define DRM_IOCTL_ETNAVIV_PM_QUERY_DOM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_DOM, struct drm_etnaviv_pm_domain)
-#define DRM_IOCTL_ETNAVIV_PM_QUERY_SIG DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_SIG, struct drm_etnaviv_pm_signal)
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* __ETNAVIV_DRM_H__ */
diff --git a/etnaviv/etnaviv_priv.h b/etnaviv/etnaviv_priv.h
index eef7f49c..fd49b959 100644
--- a/etnaviv/etnaviv_priv.h
+++ b/etnaviv/etnaviv_priv.h
@@ -45,7 +45,7 @@
#include "util_double_list.h"
#include "etnaviv_drmif.h"
-#include "etnaviv_drm.h"
+#include <drm/etnaviv_drm.h>
struct etna_bo_bucket {
uint32_t size;
diff --git a/etnaviv/meson.build b/etnaviv/meson.build
index 515a4ed0..6040cf63 100644
--- a/etnaviv/meson.build
+++ b/etnaviv/meson.build
@@ -53,7 +53,11 @@ ext_libdrm_etnaviv = declare_dependency(
)
test(
- 'etnaviv-symbol-check',
- prog_bash,
- args : [files('etnaviv-symbol-check'), libdrm_etnaviv]
+ 'etnaviv-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_etnaviv,
+ '--symbols-file', files('etnaviv-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/exynos/Makefile.am b/exynos/Makefile.am
deleted file mode 100644
index 76b185d3..00000000
--- a/exynos/Makefile.am
+++ /dev/null
@@ -1,29 +0,0 @@
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la
-libdrm_exynos_ladir = $(libdir)
-libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
-
-libdrm_exynos_la_SOURCES = \
- exynos_drm.c \
- exynos_fimg2d.c \
- fimg2d_reg.h
-
-libdrm_exynoscommonincludedir = ${includedir}/exynos
-libdrm_exynoscommoninclude_HEADERS = exynos_drm.h exynos_fimg2d.h
-
-libdrm_exynosincludedir = ${includedir}/libdrm
-libdrm_exynosinclude_HEADERS = exynos_drmif.h
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_exynos.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = exynos-symbol-check
-EXTRA_DIST = $(TESTS)
diff --git a/exynos/exynos-symbol-check b/exynos/exynos-symbol-check
deleted file mode 100755
index 49d611e6..00000000
--- a/exynos/exynos-symbol-check
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.am/libdrm_exynos*_HEADERS
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_exynos.so} | awk '{print $3}'| while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
-exynos_bo_create
-exynos_bo_destroy
-exynos_bo_from_name
-exynos_bo_get_info
-exynos_bo_get_name
-exynos_bo_handle
-exynos_bo_map
-exynos_device_create
-exynos_device_destroy
-exynos_prime_fd_to_handle
-exynos_prime_handle_to_fd
-exynos_vidi_connection
-exynos_handle_event
-g2d_blend
-g2d_copy
-g2d_copy_with_scale
-g2d_exec
-g2d_config_event
-g2d_fini
-g2d_init
-g2d_move
-g2d_scale_and_blend
-g2d_solid_fill
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/exynos/exynos-symbols.txt b/exynos/exynos-symbols.txt
new file mode 100644
index 00000000..c6748414
--- /dev/null
+++ b/exynos/exynos-symbols.txt
@@ -0,0 +1,23 @@
+exynos_bo_create
+exynos_bo_destroy
+exynos_bo_from_name
+exynos_bo_get_info
+exynos_bo_get_name
+exynos_bo_handle
+exynos_bo_map
+exynos_device_create
+exynos_device_destroy
+exynos_prime_fd_to_handle
+exynos_prime_handle_to_fd
+exynos_vidi_connection
+exynos_handle_event
+g2d_blend
+g2d_copy
+g2d_copy_with_scale
+g2d_exec
+g2d_config_event
+g2d_fini
+g2d_init
+g2d_move
+g2d_scale_and_blend
+g2d_solid_fill
diff --git a/exynos/meson.build b/exynos/meson.build
index bdfc3fc6..40d66fc1 100644
--- a/exynos/meson.build
+++ b/exynos/meson.build
@@ -47,8 +47,11 @@ pkg.generate(
)
test(
- 'exynos-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('exynos-symbol-check'), libdrm_exynos]
+ 'exynos-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_exynos,
+ '--symbols-file', files('exynos-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/freedreno/Android.bp b/freedreno/Android.bp
index 9fca9b12..ca7f3e28 100644
--- a/freedreno/Android.bp
+++ b/freedreno/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_shared {
diff --git a/freedreno/Makefile.am b/freedreno/Makefile.am
deleted file mode 100644
index 37845035..00000000
--- a/freedreno/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
-AUTOMAKE_OPTIONS=subdir-objects
-include Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- $(VALGRIND_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la
-libdrm_freedreno_ladir = $(libdir)
-libdrm_freedreno_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libdrm_freedreno_la_LIBADD = \
- ../libdrm.la \
- @PTHREADSTUBS_LIBS@ \
- @CLOCK_LIB@
-
-libdrm_freedreno_la_SOURCES = $(LIBDRM_FREEDRENO_FILES)
-if HAVE_FREEDRENO_KGSL
-libdrm_freedreno_la_SOURCES += $(LIBDRM_FREEDRENO_KGSL_FILES)
-endif
-
-libdrm_freedrenocommonincludedir = ${includedir}/freedreno
-libdrm_freedrenocommoninclude_HEADERS = $(LIBDRM_FREEDRENO_H_FILES)
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_freedreno.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = freedreno-symbol-check
-EXTRA_DIST = $(TESTS)
diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbols.txt
index 978026c0..471ca997 100755..100644
--- a/freedreno/freedreno-symbol-check
+++ b/freedreno/freedreno-symbols.txt
@@ -1,17 +1,3 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.sources/LIBDRM_FREEDRENO_H_FILES
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_freedreno.so} | awk '{print $3}'| while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
fd_bo_cpu_fini
fd_bo_cpu_prep
fd_bo_del
@@ -43,7 +29,6 @@ fd_pipe_wait
fd_pipe_wait_timeout
fd_ringbuffer_cmd_count
fd_ringbuffer_del
-fd_ringbuffer_emit_reloc_ring
fd_ringbuffer_emit_reloc_ring_full
fd_ringbuffer_flush
fd_ringbuffer_grow
@@ -58,8 +43,3 @@ fd_ringbuffer_set_parent
fd_ringbuffer_size
fd_ringbuffer_timestamp
fd_ringbuffer_flush2
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/freedreno/meson.build b/freedreno/meson.build
index c9aba060..63b84fc9 100644
--- a/freedreno/meson.build
+++ b/freedreno/meson.build
@@ -70,8 +70,11 @@ pkg.generate(
)
test(
- 'freedreno-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('freedreno-symbol-check'), libdrm_freedreno]
+ 'freedreno-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_freedreno,
+ '--symbols-file', files('freedreno-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
index 015bd9f4..7fb9c09e 100644
--- a/include/drm/amdgpu_drm.h
+++ b/include/drm/amdgpu_drm.h
@@ -125,9 +125,19 @@ extern "C" {
/* Flag that BO sharing will be explicitly synchronized */
#define AMDGPU_GEM_CREATE_EXPLICIT_SYNC (1 << 7)
/* Flag that indicates allocating MQD gart on GFX9, where the mtype
- * for the second page onward should be set to NC.
+ * for the second page onward should be set to NC. It should never
+ * be used by user space applications.
*/
-#define AMDGPU_GEM_CREATE_MQD_GFX9 (1 << 8)
+#define AMDGPU_GEM_CREATE_CP_MQD_GFX9 (1 << 8)
+/* Flag that BO may contain sensitive data that must be wiped before
+ * releasing the memory
+ */
+#define AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE (1 << 9)
+/* Flag that BO will be encrypted and that the TMZ bit should be
+ * set in the PTEs when mapping this buffer via GPUVM or
+ * accessing it with various hw blocks
+ */
+#define AMDGPU_GEM_CREATE_ENCRYPTED (1 << 10)
struct drm_amdgpu_gem_create_in {
/** the requested memory size */
@@ -204,9 +214,9 @@ union drm_amdgpu_bo_list {
/* unknown cause */
#define AMDGPU_CTX_UNKNOWN_RESET 3
-/* indicate gpu reset occurred after ctx created */
+/* indicate gpu reset occured after ctx created */
#define AMDGPU_CTX_QUERY2_FLAGS_RESET (1<<0)
-/* indicate vram lost occurred after ctx created */
+/* indicate vram lost occured after ctx created */
#define AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST (1<<1)
/* indicate some job from this context once cause gpu hang */
#define AMDGPU_CTX_QUERY2_FLAGS_GUILTY (1<<2)
@@ -219,7 +229,10 @@ union drm_amdgpu_bo_list {
#define AMDGPU_CTX_PRIORITY_VERY_LOW -1023
#define AMDGPU_CTX_PRIORITY_LOW -512
#define AMDGPU_CTX_PRIORITY_NORMAL 0
-/* Selecting a priority above NORMAL requires CAP_SYS_NICE or DRM_MASTER */
+/*
+ * When used in struct drm_amdgpu_ctx_in, a priority above NORMAL requires
+ * CAP_SYS_NICE or DRM_MASTER
+*/
#define AMDGPU_CTX_PRIORITY_HIGH 512
#define AMDGPU_CTX_PRIORITY_VERY_HIGH 1023
@@ -229,6 +242,7 @@ struct drm_amdgpu_ctx_in {
/** For future use, no flags defined so far */
__u32 flags;
__u32 ctx_id;
+ /** AMDGPU_CTX_PRIORITY_* */
__s32 priority;
};
@@ -281,6 +295,7 @@ struct drm_amdgpu_sched_in {
/* AMDGPU_SCHED_OP_* */
__u32 op;
__u32 fd;
+ /** AMDGPU_CTX_PRIORITY_* */
__s32 priority;
__u32 ctx_id;
};
@@ -336,6 +351,10 @@ struct drm_amdgpu_gem_userptr {
#define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF
#define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43
#define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1
+#define AMDGPU_TILING_DCC_INDEPENDENT_128B_SHIFT 44
+#define AMDGPU_TILING_DCC_INDEPENDENT_128B_MASK 0x1
+#define AMDGPU_TILING_SCANOUT_SHIFT 63
+#define AMDGPU_TILING_SCANOUT_MASK 0x1
/* Set/Get helpers for tiling flags. */
#define AMDGPU_TILING_SET(field, value) \
@@ -483,14 +502,16 @@ struct drm_amdgpu_gem_op {
#define AMDGPU_VM_MTYPE_MASK (0xf << 5)
/* Default MTYPE. Pre-AI must use this. Recommended for newer ASICs. */
#define AMDGPU_VM_MTYPE_DEFAULT (0 << 5)
-/* Use NC MTYPE instead of default MTYPE */
+/* Use Non Coherent MTYPE instead of default MTYPE */
#define AMDGPU_VM_MTYPE_NC (1 << 5)
-/* Use WC MTYPE instead of default MTYPE */
+/* Use Write Combine MTYPE instead of default MTYPE */
#define AMDGPU_VM_MTYPE_WC (2 << 5)
-/* Use CC MTYPE instead of default MTYPE */
+/* Use Cache Coherent MTYPE instead of default MTYPE */
#define AMDGPU_VM_MTYPE_CC (3 << 5)
-/* Use UC MTYPE instead of default MTYPE */
+/* Use UnCached MTYPE instead of default MTYPE */
#define AMDGPU_VM_MTYPE_UC (4 << 5)
+/* Use Read Write MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_RW (5 << 5)
struct drm_amdgpu_gem_va {
/** GEM object handle */
@@ -543,7 +564,7 @@ struct drm_amdgpu_cs_in {
/** Handle of resource list associated with CS */
__u32 bo_list_handle;
__u32 num_chunks;
- __u32 _pad;
+ __u32 flags;
/** this points to __u64 * which point to cs chunks */
__u64 chunks;
};
@@ -577,6 +598,14 @@ union drm_amdgpu_cs {
*/
#define AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID (1 << 4)
+/* Flag the IB as secure (TMZ)
+ */
+#define AMDGPU_IB_FLAGS_SECURE (1 << 5)
+
+/* Tell KMD to flush and invalidate caches
+ */
+#define AMDGPU_IB_FLAG_EMIT_MEM_SYNC (1 << 6)
+
struct drm_amdgpu_cs_chunk_ib {
__u32 _pad;
/** AMDGPU_IB_FLAG_* */
@@ -611,12 +640,11 @@ struct drm_amdgpu_cs_chunk_sem {
};
struct drm_amdgpu_cs_chunk_syncobj {
- __u32 handle;
- __u32 flags;
- __u64 point;
+ __u32 handle;
+ __u32 flags;
+ __u64 point;
};
-
#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1
#define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2
@@ -639,12 +667,13 @@ struct drm_amdgpu_cs_chunk_data {
};
};
-/**
+/*
* Query h/w info: Flag that this is integrated (a.h.a. fusion) GPU
*
*/
#define AMDGPU_IDS_FLAGS_FUSION 0x1
#define AMDGPU_IDS_FLAGS_PREEMPTION 0x2
+#define AMDGPU_IDS_FLAGS_TMZ 0x4
/* indicate if acceleration can be working */
#define AMDGPU_INFO_ACCEL_WORKING 0x00
@@ -693,6 +722,11 @@ struct drm_amdgpu_cs_chunk_data {
/* Subquery id: Query DMCU firmware version */
#define AMDGPU_INFO_FW_DMCU 0x12
#define AMDGPU_INFO_FW_TA 0x13
+ /* Subquery id: Query DMCUB firmware version */
+ #define AMDGPU_INFO_FW_DMCUB 0x14
+ /* Subquery id: Query TOC firmware version */
+ #define AMDGPU_INFO_FW_TOC 0x15
+
/* number of bytes moved for TTM migration */
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
/* the used VRAM size */
@@ -914,6 +948,7 @@ struct drm_amdgpu_info_firmware {
#define AMDGPU_VRAM_TYPE_DDR3 7
#define AMDGPU_VRAM_TYPE_DDR4 8
#define AMDGPU_VRAM_TYPE_GDDR6 9
+#define AMDGPU_VRAM_TYPE_DDR5 10
struct drm_amdgpu_info_device {
/** PCI Device ID */
@@ -995,6 +1030,8 @@ struct drm_amdgpu_info_device {
__u64 high_va_max;
/* gfx10 pa_sc_tile_steering_override */
__u32 pa_sc_tile_steering_override;
+ /* disabled TCCs */
+ __u64 tcc_disabled_mask;
};
struct drm_amdgpu_info_hw_ip {
@@ -1049,6 +1086,7 @@ struct drm_amdgpu_info_vce_clock_table {
#define AMDGPU_FAMILY_AI 141 /* Vega10 */
#define AMDGPU_FAMILY_RV 142 /* Raven */
#define AMDGPU_FAMILY_NV 143 /* Navi10 */
+#define AMDGPU_FAMILY_VGH 144 /* Van Gogh */
#if defined(__cplusplus)
}
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 438abde3..c7fd2a35 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -772,11 +772,12 @@ struct drm_syncobj_array {
__u32 pad;
};
+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available point on timeline syncobj */
struct drm_syncobj_timeline_array {
__u64 handles;
__u64 points;
__u32 count_handles;
- __u32 pad;
+ __u32 flags;
};
@@ -941,6 +942,8 @@ extern "C" {
#define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer)
#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
+#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
+
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 5c69090d..ed0258c6 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -58,6 +58,30 @@ extern "C" {
* may preserve meaning - such as number of planes - from the fourcc code,
* whereas others may not.
*
+ * Modifiers must uniquely encode buffer layout. In other words, a buffer must
+ * match only a single modifier. A modifier must not be a subset of layouts of
+ * another modifier. For instance, it's incorrect to encode pitch alignment in
+ * a modifier: a buffer may match a 64-pixel aligned modifier and a 32-pixel
+ * aligned modifier. That said, modifiers can have implicit minimal
+ * requirements.
+ *
+ * For modifiers where the combination of fourcc code and modifier can alias,
+ * a canonical pair needs to be defined and used by all drivers. Preferred
+ * combinations are also encouraged where all combinations might lead to
+ * confusion and unnecessarily reduced interoperability. An example for the
+ * latter is AFBC, where the ABGR layouts are preferred over ARGB layouts.
+ *
+ * There are two kinds of modifier users:
+ *
+ * - Kernel and user-space drivers: for drivers it's important that modifiers
+ * don't alias, otherwise two drivers might support the same format but use
+ * different aliases, preventing them from sharing buffers in an efficient
+ * format.
+ * - Higher-level programs interfacing with KMS/GBM/EGL/Vulkan/etc: these users
+ * see modifiers as opaque tokens they can check for equality and intersect.
+ * These users musn't need to know to reason about the modifier value
+ * (i.e. they are not expected to extract information out of the modifier).
+ *
* Vendors should document their modifier usage in as much detail as
* possible, to ensure maximum compatibility across devices, drivers and
* applications.
@@ -69,7 +93,7 @@ extern "C" {
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
((__u32)(c) << 16) | ((__u32)(d) << 24))
-#define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */
+#define DRM_FORMAT_BIG_ENDIAN (1U<<31) /* format is big endian instead of little endian */
/* Reserve 0 for the invalid format specifier */
#define DRM_FORMAT_INVALID 0
@@ -155,6 +179,12 @@ extern "C" {
#define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H') /* [63:0] A:R:G:B 16:16:16:16 little endian */
#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */
+/*
+ * RGBA format with 10-bit components packed in 64-bit per pixel, with 6 bits
+ * of unused padding per component:
+ */
+#define DRM_FORMAT_AXBXGXRX106106106106 fourcc_code('A', 'B', '1', '0') /* [63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian */
+
/* packed YCbCr */
#define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
#define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
@@ -236,6 +266,12 @@ extern "C" {
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
+/*
+ * 2 plane YCbCr
+ * index 0 = Y plane, [39:0] Y3:Y2:Y1:Y0 little endian
+ * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
+ */
+#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
/*
* 2 plane YCbCr MSB aligned
@@ -265,6 +301,22 @@ extern "C" {
*/
#define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane 16 bits per channel */
+/* 3 plane non-subsampled (444) YCbCr
+ * 16 bits per component, but only 10 bits are used and 6 bits are padded
+ * index 0: Y plane, [15:0] Y:x [10:6] little endian
+ * index 1: Cb plane, [15:0] Cb:x [10:6] little endian
+ * index 2: Cr plane, [15:0] Cr:x [10:6] little endian
+ */
+#define DRM_FORMAT_Q410 fourcc_code('Q', '4', '1', '0')
+
+/* 3 plane non-subsampled (444) YCrCb
+ * 16 bits per component, but only 10 bits are used and 6 bits are padded
+ * index 0: Y plane, [15:0] Y:x [10:6] little endian
+ * index 1: Cr plane, [15:0] Cr:x [10:6] little endian
+ * index 2: Cb plane, [15:0] Cb:x [10:6] little endian
+ */
+#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1')
+
/*
* 3 plane YCbCr
* index 0: Y plane, [7:0] Y
@@ -298,7 +350,6 @@ extern "C" {
*/
/* Vendor Ids: */
-#define DRM_FORMAT_MOD_NONE 0
#define DRM_FORMAT_MOD_VENDOR_NONE 0
#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01
#define DRM_FORMAT_MOD_VENDOR_AMD 0x02
@@ -309,6 +360,7 @@ extern "C" {
#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
#define DRM_FORMAT_MOD_VENDOR_ARM 0x08
#define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09
+#define DRM_FORMAT_MOD_VENDOR_AMLOGIC 0x0a
/* add more to the end as needed */
@@ -323,8 +375,33 @@ extern "C" {
* When adding a new token please document the layout with a code comment,
* similar to the fourcc codes above. drm_fourcc.h is considered the
* authoritative source for all of these.
+ *
+ * Generic modifier names:
+ *
+ * DRM_FORMAT_MOD_GENERIC_* definitions are used to provide vendor-neutral names
+ * for layouts which are common across multiple vendors. To preserve
+ * compatibility, in cases where a vendor-specific definition already exists and
+ * a generic name for it is desired, the common name is a purely symbolic alias
+ * and must use the same numerical value as the original definition.
+ *
+ * Note that generic names should only be used for modifiers which describe
+ * generic layouts (such as pixel re-ordering), which may have
+ * independently-developed support across multiple vendors.
+ *
+ * In future cases where a generic layout is identified before merging with a
+ * vendor-specific modifier, a new 'GENERIC' vendor or modifier using vendor
+ * 'NONE' could be considered. This should only be for obvious, exceptional
+ * cases to avoid polluting the 'GENERIC' namespace with modifiers which only
+ * apply to a single vendor.
+ *
+ * Generic names should not be used for cases where multiple hardware vendors
+ * have implementations of the same standardised compression scheme (such as
+ * AFBC). In those cases, all implementations should use the same format
+ * modifier(s), reflecting the vendor of the standard.
*/
+#define DRM_FORMAT_MOD_GENERIC_16_16_TILE DRM_FORMAT_MOD_SAMSUNG_16_16_TILE
+
/*
* Invalid Modifier
*
@@ -344,6 +421,16 @@ extern "C" {
*/
#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
+/*
+ * Deprecated: use DRM_FORMAT_MOD_LINEAR instead
+ *
+ * The "none" format modifier doesn't actually mean that the modifier is
+ * implicit, instead it means that the layout is linear. Whether modifiers are
+ * used is out-of-band information carried in an API-specific way (e.g. in a
+ * flag for drm_mode_fb_cmd2).
+ */
+#define DRM_FORMAT_MOD_NONE 0
+
/* Intel framebuffer modifiers */
/*
@@ -354,9 +441,12 @@ extern "C" {
* a platform-dependent stride. On top of that the memory can apply
* platform-depending swizzling of some higher address bits into bit6.
*
- * This format is highly platforms specific and not useful for cross-driver
- * sharing. It exists since on a given platform it does uniquely identify the
- * layout in a simple way for i915-specific userspace.
+ * Note that this layout is only accurate on intel gen 8+ or valleyview chipsets.
+ * On earlier platforms the is highly platforms specific and not useful for
+ * cross-driver sharing. It exists since on a given platform it does uniquely
+ * identify the layout in a simple way for i915-specific userspace, which
+ * facilitated conversion of userspace to modifiers. Additionally the exact
+ * format on some really old platforms is not known.
*/
#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1)
@@ -369,9 +459,12 @@ extern "C" {
* memory can apply platform-depending swizzling of some higher address bits
* into bit6.
*
- * This format is highly platforms specific and not useful for cross-driver
- * sharing. It exists since on a given platform it does uniquely identify the
- * layout in a simple way for i915-specific userspace.
+ * Note that this layout is only accurate on intel gen 8+ or valleyview chipsets.
+ * On earlier platforms the is highly platforms specific and not useful for
+ * cross-driver sharing. It exists since on a given platform it does uniquely
+ * identify the layout in a simple way for i915-specific userspace, which
+ * facilitated conversion of userspace to modifiers. Additionally the exact
+ * format on some really old platforms is not known.
*/
#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2)
@@ -411,6 +504,30 @@ extern "C" {
#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
/*
+ * Intel color control surfaces (CCS) for Gen-12 render compression.
+ *
+ * The main surface is Y-tiled and at plane index 0, the CCS is linear and
+ * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in
+ * main surface. In other words, 4 bits in CCS map to a main surface cache
+ * line pair. The main surface pitch is required to be a multiple of four
+ * Y-tile widths.
+ */
+#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS fourcc_mod_code(INTEL, 6)
+
+/*
+ * Intel color control surfaces (CCS) for Gen-12 media compression
+ *
+ * The main surface is Y-tiled and at plane index 0, the CCS is linear and
+ * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in
+ * main surface. In other words, 4 bits in CCS map to a main surface cache
+ * line pair. The main surface pitch is required to be a multiple of four
+ * Y-tile widths. For semi-planar formats like NV12, CCS planes follow the
+ * Y and UV planes i.e., planes 0 and 1 are used for Y and UV surfaces,
+ * planes 2 and 3 for the respective CCS.
+ */
+#define I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS fourcc_mod_code(INTEL, 7)
+
+/*
* Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
*
* Macroblocks are laid in a Z-shape, and each pixel data is following the
@@ -497,7 +614,113 @@ extern "C" {
#define DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED fourcc_mod_code(NVIDIA, 1)
/*
- * 16Bx2 Block Linear layout, used by desktop GPUs, and Tegra K1 and later
+ * Generalized Block Linear layout, used by desktop GPUs starting with NV50/G80,
+ * and Tegra GPUs starting with Tegra K1.
+ *
+ * Pixels are arranged in Groups of Bytes (GOBs). GOB size and layout varies
+ * based on the architecture generation. GOBs themselves are then arranged in
+ * 3D blocks, with the block dimensions (in terms of GOBs) always being a power
+ * of two, and hence expressible as their log2 equivalent (E.g., "2" represents
+ * a block depth or height of "4").
+ *
+ * Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format
+ * in full detail.
+ *
+ * Macro
+ * Bits Param Description
+ * ---- ----- -----------------------------------------------------------------
+ *
+ * 3:0 h log2(height) of each block, in GOBs. Placed here for
+ * compatibility with the existing
+ * DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK()-based modifiers.
+ *
+ * 4:4 - Must be 1, to indicate block-linear layout. Necessary for
+ * compatibility with the existing
+ * DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK()-based modifiers.
+ *
+ * 8:5 - Reserved (To support 3D-surfaces with variable log2(depth) block
+ * size). Must be zero.
+ *
+ * Note there is no log2(width) parameter. Some portions of the
+ * hardware support a block width of two gobs, but it is impractical
+ * to use due to lack of support elsewhere, and has no known
+ * benefits.
+ *
+ * 11:9 - Reserved (To support 2D-array textures with variable array stride
+ * in blocks, specified via log2(tile width in blocks)). Must be
+ * zero.
+ *
+ * 19:12 k Page Kind. This value directly maps to a field in the page
+ * tables of all GPUs >= NV50. It affects the exact layout of bits
+ * in memory and can be derived from the tuple
+ *
+ * (format, GPU model, compression type, samples per pixel)
+ *
+ * Where compression type is defined below. If GPU model were
+ * implied by the format modifier, format, or memory buffer, page
+ * kind would not need to be included in the modifier itself, but
+ * since the modifier should define the layout of the associated
+ * memory buffer independent from any device or other context, it
+ * must be included here.
+ *
+ * 21:20 g GOB Height and Page Kind Generation. The height of a GOB changed
+ * starting with Fermi GPUs. Additionally, the mapping between page
+ * kind and bit layout has changed at various points.
+ *
+ * 0 = Gob Height 8, Fermi - Volta, Tegra K1+ Page Kind mapping
+ * 1 = Gob Height 4, G80 - GT2XX Page Kind mapping
+ * 2 = Gob Height 8, Turing+ Page Kind mapping
+ * 3 = Reserved for future use.
+ *
+ * 22:22 s Sector layout. On Tegra GPUs prior to Xavier, there is a further
+ * bit remapping step that occurs at an even lower level than the
+ * page kind and block linear swizzles. This causes the layout of
+ * surfaces mapped in those SOC's GPUs to be incompatible with the
+ * equivalent mapping on other GPUs in the same system.
+ *
+ * 0 = Tegra K1 - Tegra Parker/TX2 Layout.
+ * 1 = Desktop GPU and Tegra Xavier+ Layout
+ *
+ * 25:23 c Lossless Framebuffer Compression type.
+ *
+ * 0 = none
+ * 1 = ROP/3D, layout 1, exact compression format implied by Page
+ * Kind field
+ * 2 = ROP/3D, layout 2, exact compression format implied by Page
+ * Kind field
+ * 3 = CDE horizontal
+ * 4 = CDE vertical
+ * 5 = Reserved for future use
+ * 6 = Reserved for future use
+ * 7 = Reserved for future use
+ *
+ * 55:25 - Reserved for future use. Must be zero.
+ */
+#define DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(c, s, g, k, h) \
+ fourcc_mod_code(NVIDIA, (0x10 | \
+ ((h) & 0xf) | \
+ (((k) & 0xff) << 12) | \
+ (((g) & 0x3) << 20) | \
+ (((s) & 0x1) << 22) | \
+ (((c) & 0x7) << 23)))
+
+/* To grandfather in prior block linear format modifiers to the above layout,
+ * the page kind "0", which corresponds to "pitch/linear" and hence is unusable
+ * with block-linear layouts, is remapped within drivers to the value 0xfe,
+ * which corresponds to the "generic" kind used for simple single-sample
+ * uncompressed color formats on Fermi - Volta GPUs.
+ */
+static __inline__ __u64
+drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
+{
+ if (!(modifier & 0x10) || (modifier & (0xff << 12)))
+ return modifier;
+ else
+ return modifier | (0xfe << 12);
+}
+
+/*
+ * 16Bx2 Block Linear layout, used by Tegra K1 and later
*
* Pixels are arranged in 64x8 Groups Of Bytes (GOBs). GOBs are then stacked
* vertically by a power of 2 (1 to 32 GOBs) to form a block.
@@ -518,20 +741,20 @@ extern "C" {
* in full detail.
*/
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(v) \
- fourcc_mod_code(NVIDIA, 0x10 | ((v) & 0xf))
+ DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 0, 0, 0, (v))
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB \
- fourcc_mod_code(NVIDIA, 0x10)
+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB \
- fourcc_mod_code(NVIDIA, 0x11)
+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB \
- fourcc_mod_code(NVIDIA, 0x12)
+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB \
- fourcc_mod_code(NVIDIA, 0x13)
+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB \
- fourcc_mod_code(NVIDIA, 0x14)
+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4)
#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB \
- fourcc_mod_code(NVIDIA, 0x15)
+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5)
/*
* Some Broadcom modifiers take parameters, for example the number of
@@ -648,7 +871,21 @@ extern "C" {
* Further information on the use of AFBC modifiers can be found in
* Documentation/gpu/afbc.rst
*/
-#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) fourcc_mod_code(ARM, __afbc_mode)
+
+/*
+ * The top 4 bits (out of the 56 bits alloted for specifying vendor specific
+ * modifiers) denote the category for modifiers. Currently we have only two
+ * categories of modifiers ie AFBC and MISC. We can have a maximum of sixteen
+ * different categories.
+ */
+#define DRM_FORMAT_MOD_ARM_CODE(__type, __val) \
+ fourcc_mod_code(ARM, ((__u64)(__type) << 52) | ((__val) & 0x000fffffffffffffULL))
+
+#define DRM_FORMAT_MOD_ARM_TYPE_AFBC 0x00
+#define DRM_FORMAT_MOD_ARM_TYPE_MISC 0x01
+
+#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) \
+ DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_AFBC, __afbc_mode)
/*
* AFBC superblock size
@@ -742,6 +979,28 @@ extern "C" {
*/
#define AFBC_FORMAT_MOD_BCH (1ULL << 11)
+/* AFBC uncompressed storage mode
+ *
+ * Indicates that the buffer is using AFBC uncompressed storage mode.
+ * In this mode all superblock payloads in the buffer use the uncompressed
+ * storage mode, which is usually only used for data which cannot be compressed.
+ * The buffer layout is the same as for AFBC buffers without USM set, this only
+ * affects the storage mode of the individual superblocks. Note that even a
+ * buffer without USM set may use uncompressed storage mode for some or all
+ * superblocks, USM just guarantees it for all.
+ */
+#define AFBC_FORMAT_MOD_USM (1ULL << 12)
+
+/*
+ * Arm 16x16 Block U-Interleaved modifier
+ *
+ * This is used by Arm Mali Utgard and Midgard GPUs. It divides the image
+ * into 16x16 pixel blocks. Blocks are stored linearly in order, but pixels
+ * in the block are reordered.
+ */
+#define DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED \
+ DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_MISC, 1ULL)
+
/*
* Allwinner tiled modifier
*
@@ -756,6 +1015,220 @@ extern "C" {
*/
#define DRM_FORMAT_MOD_ALLWINNER_TILED fourcc_mod_code(ALLWINNER, 1)
+/*
+ * Amlogic Video Framebuffer Compression modifiers
+ *
+ * Amlogic uses a proprietary lossless image compression protocol and format
+ * for their hardware video codec accelerators, either video decoders or
+ * video input encoders.
+ *
+ * It considerably reduces memory bandwidth while writing and reading
+ * frames in memory.
+ *
+ * The underlying storage is considered to be 3 components, 8bit or 10-bit
+ * per component YCbCr 420, single plane :
+ * - DRM_FORMAT_YUV420_8BIT
+ * - DRM_FORMAT_YUV420_10BIT
+ *
+ * The first 8 bits of the mode defines the layout, then the following 8 bits
+ * defines the options changing the layout.
+ *
+ * Not all combinations are valid, and different SoCs may support different
+ * combinations of layout and options.
+ */
+#define __fourcc_mod_amlogic_layout_mask 0xf
+#define __fourcc_mod_amlogic_options_shift 8
+#define __fourcc_mod_amlogic_options_mask 0xf
+
+#define DRM_FORMAT_MOD_AMLOGIC_FBC(__layout, __options) \
+ fourcc_mod_code(AMLOGIC, \
+ ((__layout) & __fourcc_mod_amlogic_layout_mask) | \
+ (((__options) & __fourcc_mod_amlogic_options_mask) \
+ << __fourcc_mod_amlogic_options_shift))
+
+/* Amlogic FBC Layouts */
+
+/*
+ * Amlogic FBC Basic Layout
+ *
+ * The basic layout is composed of:
+ * - a body content organized in 64x32 superblocks with 4096 bytes per
+ * superblock in default mode.
+ * - a 32 bytes per 128x64 header block
+ *
+ * This layout is transferrable between Amlogic SoCs supporting this modifier.
+ */
+#define AMLOGIC_FBC_LAYOUT_BASIC (1ULL)
+
+/*
+ * Amlogic FBC Scatter Memory layout
+ *
+ * Indicates the header contains IOMMU references to the compressed
+ * frames content to optimize memory access and layout.
+ *
+ * In this mode, only the header memory address is needed, thus the
+ * content memory organization is tied to the current producer
+ * execution and cannot be saved/dumped neither transferrable between
+ * Amlogic SoCs supporting this modifier.
+ *
+ * Due to the nature of the layout, these buffers are not expected to
+ * be accessible by the user-space clients, but only accessible by the
+ * hardware producers and consumers.
+ *
+ * The user-space clients should expect a failure while trying to mmap
+ * the DMA-BUF handle returned by the producer.
+ */
+#define AMLOGIC_FBC_LAYOUT_SCATTER (2ULL)
+
+/* Amlogic FBC Layout Options Bit Mask */
+
+/*
+ * Amlogic FBC Memory Saving mode
+ *
+ * Indicates the storage is packed when pixel size is multiple of word
+ * boudaries, i.e. 8bit should be stored in this mode to save allocation
+ * memory.
+ *
+ * This mode reduces body layout to 3072 bytes per 64x32 superblock with
+ * the basic layout and 3200 bytes per 64x32 superblock combined with
+ * the scatter layout.
+ */
+#define AMLOGIC_FBC_OPTION_MEM_SAVING (1ULL << 0)
+
+/*
+ * AMD modifiers
+ *
+ * Memory layout:
+ *
+ * without DCC:
+ * - main surface
+ *
+ * with DCC & without DCC_RETILE:
+ * - main surface in plane 0
+ * - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is set)
+ *
+ * with DCC & DCC_RETILE:
+ * - main surface in plane 0
+ * - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned)
+ * - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
+ *
+ * For multi-plane formats the above surfaces get merged into one plane for
+ * each format plane, based on the required alignment only.
+ *
+ * Bits Parameter Notes
+ * ----- ------------------------ ---------------------------------------------
+ *
+ * 7:0 TILE_VERSION Values are AMD_FMT_MOD_TILE_VER_*
+ * 12:8 TILE Values are AMD_FMT_MOD_TILE_<version>_*
+ * 13 DCC
+ * 14 DCC_RETILE
+ * 15 DCC_PIPE_ALIGN
+ * 16 DCC_INDEPENDENT_64B
+ * 17 DCC_INDEPENDENT_128B
+ * 19:18 DCC_MAX_COMPRESSED_BLOCK Values are AMD_FMT_MOD_DCC_BLOCK_*
+ * 20 DCC_CONSTANT_ENCODE
+ * 23:21 PIPE_XOR_BITS Only for some chips
+ * 26:24 BANK_XOR_BITS Only for some chips
+ * 29:27 PACKERS Only for some chips
+ * 32:30 RB Only for some chips
+ * 35:33 PIPE Only for some chips
+ * 55:36 - Reserved for future use, must be zero
+ */
+#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
+
+#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
+
+/* Reserve 0 for GFX8 and older */
+#define AMD_FMT_MOD_TILE_VER_GFX9 1
+#define AMD_FMT_MOD_TILE_VER_GFX10 2
+#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
+
+/*
+ * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical
+ * version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
+
+/*
+ * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
+ * GFX9 as canonical version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
+#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
+#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
+#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
+
+#define AMD_FMT_MOD_DCC_BLOCK_64B 0
+#define AMD_FMT_MOD_DCC_BLOCK_128B 1
+#define AMD_FMT_MOD_DCC_BLOCK_256B 2
+
+#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0
+#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF
+#define AMD_FMT_MOD_TILE_SHIFT 8
+#define AMD_FMT_MOD_TILE_MASK 0x1F
+
+/* Whether DCC compression is enabled. */
+#define AMD_FMT_MOD_DCC_SHIFT 13
+#define AMD_FMT_MOD_DCC_MASK 0x1
+
+/*
+ * Whether to include two DCC surfaces, one which is rb & pipe aligned, and
+ * one which is not-aligned.
+ */
+#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14
+#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1
+
+/* Only set if DCC_RETILE = false */
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1
+
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3
+
+/*
+ * DCC supports embedding some clear colors directly in the DCC surface.
+ * However, on older GPUs the rendering HW ignores the embedded clear color
+ * and prefers the driver provided color. This necessitates doing a fastclear
+ * eliminate operation before a process transfers control.
+ *
+ * If this bit is set that means the fastclear eliminate is not needed for these
+ * embeddable colors.
+ */
+#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 20
+#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_MASK 0x1
+
+/*
+ * The below fields are for accounting for per GPU differences. These are only
+ * relevant for GFX9 and later and if the tile field is *_X/_T.
+ *
+ * PIPE_XOR_BITS = always needed
+ * BANK_XOR_BITS = only for TILE_VER_GFX9
+ * PACKERS = only for TILE_VER_GFX10_RBPLUS
+ * RB = only for TILE_VER_GFX9 & DCC
+ * PIPE = only for TILE_VER_GFX9 & DCC & (DCC_RETILE | DCC_PIPE_ALIGN)
+ */
+#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 21
+#define AMD_FMT_MOD_PIPE_XOR_BITS_MASK 0x7
+#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 24
+#define AMD_FMT_MOD_BANK_XOR_BITS_MASK 0x7
+#define AMD_FMT_MOD_PACKERS_SHIFT 27
+#define AMD_FMT_MOD_PACKERS_MASK 0x7
+#define AMD_FMT_MOD_RB_SHIFT 30
+#define AMD_FMT_MOD_RB_MASK 0x7
+#define AMD_FMT_MOD_PIPE_SHIFT 33
+#define AMD_FMT_MOD_PIPE_MASK 0x7
+
+#define AMD_FMT_MOD_SET(field, value) \
+ ((uint64_t)(value) << AMD_FMT_MOD_##field##_SHIFT)
+#define AMD_FMT_MOD_GET(field, value) \
+ (((value) >> AMD_FMT_MOD_##field##_SHIFT) & AMD_FMT_MOD_##field##_MASK)
+#define AMD_FMT_MOD_CLEAR(field) \
+ (~((uint64_t)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT))
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 5fe6c649..96416e6d 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -33,6 +33,15 @@
extern "C" {
#endif
+/**
+ * DOC: overview
+ *
+ * DRM exposes many UAPI and structure definition to have a consistent
+ * and standardized interface with user.
+ * Userspace can refer to these structure definitions and UAPI formats
+ * to communicate to driver
+ */
+
#define DRM_CONNECTOR_NAME_LEN 32
#define DRM_DISPLAY_MODE_LEN 32
#define DRM_PROP_NAME_LEN 32
@@ -323,14 +332,19 @@ struct drm_mode_get_encoder {
/* This is for connectors with multiple signal types. */
/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
enum drm_mode_subconnector {
- DRM_MODE_SUBCONNECTOR_Automatic = 0,
- DRM_MODE_SUBCONNECTOR_Unknown = 0,
- DRM_MODE_SUBCONNECTOR_DVID = 3,
- DRM_MODE_SUBCONNECTOR_DVIA = 4,
- DRM_MODE_SUBCONNECTOR_Composite = 5,
- DRM_MODE_SUBCONNECTOR_SVIDEO = 6,
- DRM_MODE_SUBCONNECTOR_Component = 8,
- DRM_MODE_SUBCONNECTOR_SCART = 9,
+ DRM_MODE_SUBCONNECTOR_Automatic = 0, /* DVI-I, TV */
+ DRM_MODE_SUBCONNECTOR_Unknown = 0, /* DVI-I, TV, DP */
+ DRM_MODE_SUBCONNECTOR_VGA = 1, /* DP */
+ DRM_MODE_SUBCONNECTOR_DVID = 3, /* DVI-I DP */
+ DRM_MODE_SUBCONNECTOR_DVIA = 4, /* DVI-I */
+ DRM_MODE_SUBCONNECTOR_Composite = 5, /* TV */
+ DRM_MODE_SUBCONNECTOR_SVIDEO = 6, /* TV */
+ DRM_MODE_SUBCONNECTOR_Component = 8, /* TV */
+ DRM_MODE_SUBCONNECTOR_SCART = 9, /* TV */
+ DRM_MODE_SUBCONNECTOR_DisplayPort = 10, /* DP */
+ DRM_MODE_SUBCONNECTOR_HDMIA = 11, /* DP */
+ DRM_MODE_SUBCONNECTOR_Native = 15, /* DP */
+ DRM_MODE_SUBCONNECTOR_Wireless = 18, /* DP */
};
#define DRM_MODE_CONNECTOR_Unknown 0
@@ -352,6 +366,7 @@ enum drm_mode_subconnector {
#define DRM_MODE_CONNECTOR_DSI 16
#define DRM_MODE_CONNECTOR_DPI 17
#define DRM_MODE_CONNECTOR_WRITEBACK 18
+#define DRM_MODE_CONNECTOR_SPI 19
struct drm_mode_get_connector {
@@ -487,7 +502,7 @@ struct drm_mode_fb_cmd2 {
* In case of planar formats, this ioctl allows up to 4
* buffer objects with offsets and pitches per plane.
* The pitch and offset order is dictated by the fourcc,
- * e.g. NV12 (http://fourcc.org/yuv.php#NV12) is described as:
+ * e.g. NV12 (https://fourcc.org/yuv.php#NV12) is described as:
*
* YUV 4:2:0 image with a plane of 8 bit Y samples
* followed by an interleaved U/V plane containing
@@ -630,6 +645,92 @@ struct drm_color_lut {
__u16 reserved;
};
+/**
+ * struct hdr_metadata_infoframe - HDR Metadata Infoframe Data.
+ *
+ * HDR Metadata Infoframe as per CTA 861.G spec. This is expected
+ * to match exactly with the spec.
+ *
+ * Userspace is expected to pass the metadata information as per
+ * the format described in this structure.
+ */
+struct hdr_metadata_infoframe {
+ /**
+ * @eotf: Electro-Optical Transfer Function (EOTF)
+ * used in the stream.
+ */
+ __u8 eotf;
+ /**
+ * @metadata_type: Static_Metadata_Descriptor_ID.
+ */
+ __u8 metadata_type;
+ /**
+ * @display_primaries: Color Primaries of the Data.
+ * These are coded as unsigned 16-bit values in units of
+ * 0.00002, where 0x0000 represents zero and 0xC350
+ * represents 1.0000.
+ * @display_primaries.x: X cordinate of color primary.
+ * @display_primaries.y: Y cordinate of color primary.
+ */
+ struct {
+ __u16 x, y;
+ } display_primaries[3];
+ /**
+ * @white_point: White Point of Colorspace Data.
+ * These are coded as unsigned 16-bit values in units of
+ * 0.00002, where 0x0000 represents zero and 0xC350
+ * represents 1.0000.
+ * @white_point.x: X cordinate of whitepoint of color primary.
+ * @white_point.y: Y cordinate of whitepoint of color primary.
+ */
+ struct {
+ __u16 x, y;
+ } white_point;
+ /**
+ * @max_display_mastering_luminance: Max Mastering Display Luminance.
+ * This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
+ * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
+ */
+ __u16 max_display_mastering_luminance;
+ /**
+ * @min_display_mastering_luminance: Min Mastering Display Luminance.
+ * This value is coded as an unsigned 16-bit value in units of
+ * 0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
+ * represents 6.5535 cd/m2.
+ */
+ __u16 min_display_mastering_luminance;
+ /**
+ * @max_cll: Max Content Light Level.
+ * This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
+ * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
+ */
+ __u16 max_cll;
+ /**
+ * @max_fall: Max Frame Average Light Level.
+ * This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
+ * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
+ */
+ __u16 max_fall;
+};
+
+/**
+ * struct hdr_output_metadata - HDR output metadata
+ *
+ * Metadata Information to be passed from userspace
+ */
+struct hdr_output_metadata {
+ /**
+ * @metadata_type: Static_Metadata_Descriptor_ID.
+ */
+ __u32 metadata_type;
+ /**
+ * @hdmi_metadata_type1: HDR Metadata Infoframe.
+ */
+ union {
+ struct hdr_metadata_infoframe hdmi_metadata_type1;
+ };
+};
+
#define DRM_MODE_PAGE_FLIP_EVENT 0x01
#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
@@ -803,6 +904,10 @@ struct drm_format_modifier {
};
/**
+ * struct drm_mode_create_blob - Create New block property
+ * @data: Pointer to data to copy.
+ * @length: Length of data to copy.
+ * @blob_id: new property ID.
* Create a new 'blob' data property, copying length bytes from data pointer,
* and returning new blob ID.
*/
@@ -816,13 +921,27 @@ struct drm_mode_create_blob {
};
/**
+ * struct drm_mode_destroy_blob - Destroy user blob
+ * @blob_id: blob_id to destroy
* Destroy a user-created blob property.
+ *
+ * User-space can release blobs as soon as they do not need to refer to them by
+ * their blob object ID. For instance, if you are using a MODE_ID blob in an
+ * atomic commit and you will not make another commit re-using the same ID, you
+ * can destroy the blob as soon as the commit has been issued, without waiting
+ * for it to complete.
*/
struct drm_mode_destroy_blob {
__u32 blob_id;
};
/**
+ * struct drm_mode_create_lease - Create lease
+ * @object_ids: Pointer to array of object ids.
+ * @object_count: Number of object ids.
+ * @flags: flags for new FD.
+ * @lessee_id: unique identifier for lessee.
+ * @fd: file descriptor to new drm_master file.
* Lease mode resources, creating another drm_master.
*/
struct drm_mode_create_lease {
@@ -840,6 +959,10 @@ struct drm_mode_create_lease {
};
/**
+ * struct drm_mode_list_lessees - List lessees
+ * @count_lessees: Number of lessees.
+ * @pad: pad.
+ * @lessees_ptr: Pointer to lessess.
* List lesses from a drm_master
*/
struct drm_mode_list_lessees {
@@ -860,6 +983,10 @@ struct drm_mode_list_lessees {
};
/**
+ * struct drm_mode_get_lease - Get Lease
+ * @count_objects: Number of leased objects.
+ * @pad: pad.
+ * @objects_ptr: Pointer to objects.
* Get leased objects
*/
struct drm_mode_get_lease {
@@ -880,6 +1007,8 @@ struct drm_mode_get_lease {
};
/**
+ * struct drm_mode_revoke_lease - Revoke lease
+ * @lessee_id: Unique ID of lessee.
* Revoke lease
*/
struct drm_mode_revoke_lease {
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h
index d42105c8..4f941489 100644
--- a/include/drm/nouveau_drm.h
+++ b/include/drm/nouveau_drm.h
@@ -73,15 +73,11 @@ struct drm_nouveau_gpuobj_free {
uint32_t handle;
};
-/* FIXME : maybe unify {GET,SET}PARAMs */
#define NOUVEAU_GETPARAM_PCI_VENDOR 3
#define NOUVEAU_GETPARAM_PCI_DEVICE 4
#define NOUVEAU_GETPARAM_BUS_TYPE 5
-#define NOUVEAU_GETPARAM_FB_PHYSICAL 6
-#define NOUVEAU_GETPARAM_AGP_PHYSICAL 7
#define NOUVEAU_GETPARAM_FB_SIZE 8
#define NOUVEAU_GETPARAM_AGP_SIZE 9
-#define NOUVEAU_GETPARAM_PCI_PHYSICAL 10
#define NOUVEAU_GETPARAM_CHIPSET_ID 11
#define NOUVEAU_GETPARAM_VM_VRAM_BASE 12
#define NOUVEAU_GETPARAM_GRAPH_UNITS 13
@@ -175,12 +171,12 @@ struct drm_nouveau_gem_pushbuf {
__u64 push;
__u32 suffix0;
__u32 suffix1;
+#define NOUVEAU_GEM_PUSHBUF_SYNC (1ULL << 0)
__u64 vram_available;
__u64 gart_available;
};
#define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001
-#define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002
#define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004
struct drm_nouveau_gem_cpu_prep {
__u32 handle;
@@ -191,29 +187,68 @@ struct drm_nouveau_gem_cpu_fini {
__u32 handle;
};
-enum nouveau_bus_type {
- NV_AGP = 0,
- NV_PCI = 1,
- NV_PCIE = 2,
-};
-
-struct drm_nouveau_sarea {
-};
-
-#define DRM_NOUVEAU_GETPARAM 0x00
-#define DRM_NOUVEAU_SETPARAM 0x01
-#define DRM_NOUVEAU_CHANNEL_ALLOC 0x02
-#define DRM_NOUVEAU_CHANNEL_FREE 0x03
-#define DRM_NOUVEAU_GROBJ_ALLOC 0x04
-#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05
-#define DRM_NOUVEAU_GPUOBJ_FREE 0x06
+#define DRM_NOUVEAU_GETPARAM 0x00 /* deprecated */
+#define DRM_NOUVEAU_SETPARAM 0x01 /* deprecated */
+#define DRM_NOUVEAU_CHANNEL_ALLOC 0x02 /* deprecated */
+#define DRM_NOUVEAU_CHANNEL_FREE 0x03 /* deprecated */
+#define DRM_NOUVEAU_GROBJ_ALLOC 0x04 /* deprecated */
+#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05 /* deprecated */
+#define DRM_NOUVEAU_GPUOBJ_FREE 0x06 /* deprecated */
#define DRM_NOUVEAU_NVIF 0x07
+#define DRM_NOUVEAU_SVM_INIT 0x08
+#define DRM_NOUVEAU_SVM_BIND 0x09
#define DRM_NOUVEAU_GEM_NEW 0x40
#define DRM_NOUVEAU_GEM_PUSHBUF 0x41
#define DRM_NOUVEAU_GEM_CPU_PREP 0x42
#define DRM_NOUVEAU_GEM_CPU_FINI 0x43
#define DRM_NOUVEAU_GEM_INFO 0x44
+struct drm_nouveau_svm_init {
+ __u64 unmanaged_addr;
+ __u64 unmanaged_size;
+};
+
+struct drm_nouveau_svm_bind {
+ __u64 header;
+ __u64 va_start;
+ __u64 va_end;
+ __u64 npages;
+ __u64 stride;
+ __u64 result;
+ __u64 reserved0;
+ __u64 reserved1;
+};
+
+#define NOUVEAU_SVM_BIND_COMMAND_SHIFT 0
+#define NOUVEAU_SVM_BIND_COMMAND_BITS 8
+#define NOUVEAU_SVM_BIND_COMMAND_MASK ((1 << 8) - 1)
+#define NOUVEAU_SVM_BIND_PRIORITY_SHIFT 8
+#define NOUVEAU_SVM_BIND_PRIORITY_BITS 8
+#define NOUVEAU_SVM_BIND_PRIORITY_MASK ((1 << 8) - 1)
+#define NOUVEAU_SVM_BIND_TARGET_SHIFT 16
+#define NOUVEAU_SVM_BIND_TARGET_BITS 32
+#define NOUVEAU_SVM_BIND_TARGET_MASK 0xffffffff
+
+/*
+ * Below is use to validate ioctl argument, userspace can also use it to make
+ * sure that no bit are set beyond known fields for a given kernel version.
+ */
+#define NOUVEAU_SVM_BIND_VALID_BITS 48
+#define NOUVEAU_SVM_BIND_VALID_MASK ((1ULL << NOUVEAU_SVM_BIND_VALID_BITS) - 1)
+
+
+/*
+ * NOUVEAU_BIND_COMMAND__MIGRATE: synchronous migrate to target memory.
+ * result: number of page successfuly migrate to the target memory.
+ */
+#define NOUVEAU_SVM_BIND_COMMAND__MIGRATE 0
+
+/*
+ * NOUVEAU_SVM_BIND_HEADER_TARGET__GPU_VRAM: target the GPU VRAM memory.
+ */
+#define NOUVEAU_SVM_BIND_TARGET__GPU_VRAM (1UL << 31)
+
+
#if defined(__cplusplus)
}
#endif
diff --git a/intel/Android.bp b/intel/Android.bp
index 22713acc..7c82f1e6 100644
--- a/intel/Android.bp
+++ b/intel/Android.bp
@@ -21,6 +21,16 @@
// IN THE SOFTWARE.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-BSD
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_shared {
diff --git a/intel/Makefile.am b/intel/Makefile.am
deleted file mode 100644
index bad44f5f..00000000
--- a/intel/Makefile.am
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright © 2008 Intel Corporation
-#
-# 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 AUTHORS OR COPYRIGHT HOLDERS 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.
-#
-# Authors:
-# Eric Anholt <eric@anholt.net>
-
-include Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- $(PCIACCESS_CFLAGS) \
- $(VALGRIND_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_intel_la_LTLIBRARIES = libdrm_intel.la
-libdrm_intel_ladir = $(libdir)
-libdrm_intel_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libdrm_intel_la_LIBADD = ../libdrm.la \
- @PTHREADSTUBS_LIBS@ \
- @PCIACCESS_LIBS@ \
- @CLOCK_LIB@
-
-libdrm_intel_la_SOURCES = $(LIBDRM_INTEL_FILES)
-
-libdrm_intelincludedir = ${includedir}/libdrm
-libdrm_intelinclude_HEADERS = $(LIBDRM_INTEL_H_FILES)
-
-# This may be interesting even outside of "make check", due to the -dump option.
-noinst_PROGRAMS = test_decode
-
-BATCHES = \
- tests/gen4-3d.batch \
- tests/gm45-3d.batch \
- tests/gen5-3d.batch \
- tests/gen6-3d.batch \
- tests/gen7-2d-copy.batch \
- tests/gen7-3d.batch
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = \
- $(BATCHES:.batch=.batch.sh) \
- intel-symbol-check
-
-EXTRA_DIST = \
- $(BATCHES) \
- $(BATCHES:.batch=.batch.sh) \
- $(BATCHES:.batch=.batch-ref.txt) \
- $(BATCHES:.batch=.batch-ref.txt) \
- tests/test-batch.sh \
- $(TESTS)
-
-test_decode_LDADD = libdrm_intel.la ../libdrm.la
-
-pkgconfig_DATA = libdrm_intel.pc
diff --git a/intel/i915_pciids.h b/intel/i915_pciids.h
index c7cdbfc4..ebd0dd1c 100644
--- a/intel/i915_pciids.h
+++ b/intel/i915_pciids.h
@@ -108,8 +108,10 @@
INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \
INTEL_VGA_DEVICE(0x2e92, info) /* B43_G.1 */
-#define INTEL_PINEVIEW_IDS(info) \
- INTEL_VGA_DEVICE(0xa001, info), \
+#define INTEL_PINEVIEW_G_IDS(info) \
+ INTEL_VGA_DEVICE(0xa001, info)
+
+#define INTEL_PINEVIEW_M_IDS(info) \
INTEL_VGA_DEVICE(0xa011, info)
#define INTEL_IRONLAKE_D_IDS(info) \
@@ -166,71 +168,86 @@
#define INTEL_IVB_Q_IDS(info) \
INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */
+#define INTEL_HSW_ULT_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x0A02, info), /* ULT GT1 desktop */ \
+ INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \
+ INTEL_VGA_DEVICE(0x0A0A, info), /* ULT GT1 server */ \
+ INTEL_VGA_DEVICE(0x0A0B, info) /* ULT GT1 reserved */
+
+#define INTEL_HSW_ULX_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x0A0E, info) /* ULX GT1 mobile */
+
#define INTEL_HSW_GT1_IDS(info) \
+ INTEL_HSW_ULT_GT1_IDS(info), \
+ INTEL_HSW_ULX_GT1_IDS(info), \
INTEL_VGA_DEVICE(0x0402, info), /* GT1 desktop */ \
- INTEL_VGA_DEVICE(0x040a, info), /* GT1 server */ \
+ INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \
+ INTEL_VGA_DEVICE(0x040A, info), /* GT1 server */ \
INTEL_VGA_DEVICE(0x040B, info), /* GT1 reserved */ \
INTEL_VGA_DEVICE(0x040E, info), /* GT1 reserved */ \
INTEL_VGA_DEVICE(0x0C02, info), /* SDV GT1 desktop */ \
+ INTEL_VGA_DEVICE(0x0C06, info), /* SDV GT1 mobile */ \
INTEL_VGA_DEVICE(0x0C0A, info), /* SDV GT1 server */ \
INTEL_VGA_DEVICE(0x0C0B, info), /* SDV GT1 reserved */ \
INTEL_VGA_DEVICE(0x0C0E, info), /* SDV GT1 reserved */ \
- INTEL_VGA_DEVICE(0x0A02, info), /* ULT GT1 desktop */ \
- INTEL_VGA_DEVICE(0x0A0A, info), /* ULT GT1 server */ \
- INTEL_VGA_DEVICE(0x0A0B, info), /* ULT GT1 reserved */ \
INTEL_VGA_DEVICE(0x0D02, info), /* CRW GT1 desktop */ \
+ INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \
INTEL_VGA_DEVICE(0x0D0A, info), /* CRW GT1 server */ \
INTEL_VGA_DEVICE(0x0D0B, info), /* CRW GT1 reserved */ \
- INTEL_VGA_DEVICE(0x0D0E, info), /* CRW GT1 reserved */ \
- INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \
- INTEL_VGA_DEVICE(0x0C06, info), /* SDV GT1 mobile */ \
- INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \
- INTEL_VGA_DEVICE(0x0A0E, info), /* ULX GT1 mobile */ \
- INTEL_VGA_DEVICE(0x0D06, info) /* CRW GT1 mobile */
+ INTEL_VGA_DEVICE(0x0D0E, info) /* CRW GT1 reserved */
+
+#define INTEL_HSW_ULT_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x0A12, info), /* ULT GT2 desktop */ \
+ INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \
+ INTEL_VGA_DEVICE(0x0A1A, info), /* ULT GT2 server */ \
+ INTEL_VGA_DEVICE(0x0A1B, info) /* ULT GT2 reserved */ \
+
+#define INTEL_HSW_ULX_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x0A1E, info) /* ULX GT2 mobile */ \
#define INTEL_HSW_GT2_IDS(info) \
+ INTEL_HSW_ULT_GT2_IDS(info), \
+ INTEL_HSW_ULX_GT2_IDS(info), \
INTEL_VGA_DEVICE(0x0412, info), /* GT2 desktop */ \
- INTEL_VGA_DEVICE(0x041a, info), /* GT2 server */ \
+ INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \
+ INTEL_VGA_DEVICE(0x041A, info), /* GT2 server */ \
INTEL_VGA_DEVICE(0x041B, info), /* GT2 reserved */ \
INTEL_VGA_DEVICE(0x041E, info), /* GT2 reserved */ \
INTEL_VGA_DEVICE(0x0C12, info), /* SDV GT2 desktop */ \
+ INTEL_VGA_DEVICE(0x0C16, info), /* SDV GT2 mobile */ \
INTEL_VGA_DEVICE(0x0C1A, info), /* SDV GT2 server */ \
INTEL_VGA_DEVICE(0x0C1B, info), /* SDV GT2 reserved */ \
INTEL_VGA_DEVICE(0x0C1E, info), /* SDV GT2 reserved */ \
- INTEL_VGA_DEVICE(0x0A12, info), /* ULT GT2 desktop */ \
- INTEL_VGA_DEVICE(0x0A1A, info), /* ULT GT2 server */ \
- INTEL_VGA_DEVICE(0x0A1B, info), /* ULT GT2 reserved */ \
INTEL_VGA_DEVICE(0x0D12, info), /* CRW GT2 desktop */ \
+ INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \
INTEL_VGA_DEVICE(0x0D1A, info), /* CRW GT2 server */ \
INTEL_VGA_DEVICE(0x0D1B, info), /* CRW GT2 reserved */ \
- INTEL_VGA_DEVICE(0x0D1E, info), /* CRW GT2 reserved */ \
- INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \
- INTEL_VGA_DEVICE(0x0426, info), /* GT2 mobile */ \
- INTEL_VGA_DEVICE(0x0C16, info), /* SDV GT2 mobile */ \
- INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \
- INTEL_VGA_DEVICE(0x0A1E, info), /* ULX GT2 mobile */ \
- INTEL_VGA_DEVICE(0x0D16, info) /* CRW GT2 mobile */
+ INTEL_VGA_DEVICE(0x0D1E, info) /* CRW GT2 reserved */
+
+#define INTEL_HSW_ULT_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x0A22, info), /* ULT GT3 desktop */ \
+ INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \
+ INTEL_VGA_DEVICE(0x0A2A, info), /* ULT GT3 server */ \
+ INTEL_VGA_DEVICE(0x0A2B, info), /* ULT GT3 reserved */ \
+ INTEL_VGA_DEVICE(0x0A2E, info) /* ULT GT3 reserved */
#define INTEL_HSW_GT3_IDS(info) \
+ INTEL_HSW_ULT_GT3_IDS(info), \
INTEL_VGA_DEVICE(0x0422, info), /* GT3 desktop */ \
- INTEL_VGA_DEVICE(0x042a, info), /* GT3 server */ \
+ INTEL_VGA_DEVICE(0x0426, info), /* GT3 mobile */ \
+ INTEL_VGA_DEVICE(0x042A, info), /* GT3 server */ \
INTEL_VGA_DEVICE(0x042B, info), /* GT3 reserved */ \
INTEL_VGA_DEVICE(0x042E, info), /* GT3 reserved */ \
INTEL_VGA_DEVICE(0x0C22, info), /* SDV GT3 desktop */ \
+ INTEL_VGA_DEVICE(0x0C26, info), /* SDV GT3 mobile */ \
INTEL_VGA_DEVICE(0x0C2A, info), /* SDV GT3 server */ \
INTEL_VGA_DEVICE(0x0C2B, info), /* SDV GT3 reserved */ \
INTEL_VGA_DEVICE(0x0C2E, info), /* SDV GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0A22, info), /* ULT GT3 desktop */ \
- INTEL_VGA_DEVICE(0x0A2A, info), /* ULT GT3 server */ \
- INTEL_VGA_DEVICE(0x0A2B, info), /* ULT GT3 reserved */ \
INTEL_VGA_DEVICE(0x0D22, info), /* CRW GT3 desktop */ \
+ INTEL_VGA_DEVICE(0x0D26, info), /* CRW GT3 mobile */ \
INTEL_VGA_DEVICE(0x0D2A, info), /* CRW GT3 server */ \
INTEL_VGA_DEVICE(0x0D2B, info), /* CRW GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0D2E, info), /* CRW GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0C26, info), /* SDV GT3 mobile */ \
- INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \
- INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0D26, info) /* CRW GT3 mobile */
+ INTEL_VGA_DEVICE(0x0D2E, info) /* CRW GT3 reserved */
#define INTEL_HSW_IDS(info) \
INTEL_HSW_GT1_IDS(info), \
@@ -241,39 +258,61 @@
INTEL_VGA_DEVICE(0x0f30, info), \
INTEL_VGA_DEVICE(0x0f31, info), \
INTEL_VGA_DEVICE(0x0f32, info), \
- INTEL_VGA_DEVICE(0x0f33, info), \
- INTEL_VGA_DEVICE(0x0157, info), \
- INTEL_VGA_DEVICE(0x0155, info)
+ INTEL_VGA_DEVICE(0x0f33, info)
-#define INTEL_BDW_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \
+#define INTEL_BDW_ULT_GT1_IDS(info) \
INTEL_VGA_DEVICE(0x1606, info), /* GT1 ULT */ \
- INTEL_VGA_DEVICE(0x160B, info), /* GT1 Iris */ \
- INTEL_VGA_DEVICE(0x160E, info), /* GT1 ULX */ \
+ INTEL_VGA_DEVICE(0x160B, info) /* GT1 Iris */
+
+#define INTEL_BDW_ULX_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x160E, info) /* GT1 ULX */
+
+#define INTEL_BDW_GT1_IDS(info) \
+ INTEL_BDW_ULT_GT1_IDS(info), \
+ INTEL_BDW_ULX_GT1_IDS(info), \
+ INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \
INTEL_VGA_DEVICE(0x160A, info), /* GT1 Server */ \
INTEL_VGA_DEVICE(0x160D, info) /* GT1 Workstation */
-#define INTEL_BDW_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */ \
+#define INTEL_BDW_ULT_GT2_IDS(info) \
INTEL_VGA_DEVICE(0x1616, info), /* GT2 ULT */ \
- INTEL_VGA_DEVICE(0x161B, info), /* GT2 ULT */ \
- INTEL_VGA_DEVICE(0x161E, info), /* GT2 ULX */ \
+ INTEL_VGA_DEVICE(0x161B, info) /* GT2 ULT */
+
+#define INTEL_BDW_ULX_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x161E, info) /* GT2 ULX */
+
+#define INTEL_BDW_GT2_IDS(info) \
+ INTEL_BDW_ULT_GT2_IDS(info), \
+ INTEL_BDW_ULX_GT2_IDS(info), \
+ INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */ \
INTEL_VGA_DEVICE(0x161A, info), /* GT2 Server */ \
INTEL_VGA_DEVICE(0x161D, info) /* GT2 Workstation */
+#define INTEL_BDW_ULT_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \
+ INTEL_VGA_DEVICE(0x162B, info) /* Iris */ \
+
+#define INTEL_BDW_ULX_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x162E, info) /* ULX */
+
#define INTEL_BDW_GT3_IDS(info) \
+ INTEL_BDW_ULT_GT3_IDS(info), \
+ INTEL_BDW_ULX_GT3_IDS(info), \
INTEL_VGA_DEVICE(0x1622, info), /* ULT */ \
- INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \
- INTEL_VGA_DEVICE(0x162B, info), /* Iris */ \
- INTEL_VGA_DEVICE(0x162E, info), /* ULX */\
INTEL_VGA_DEVICE(0x162A, info), /* Server */ \
INTEL_VGA_DEVICE(0x162D, info) /* Workstation */
+#define INTEL_BDW_ULT_RSVD_IDS(info) \
+ INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \
+ INTEL_VGA_DEVICE(0x163B, info) /* Iris */
+
+#define INTEL_BDW_ULX_RSVD_IDS(info) \
+ INTEL_VGA_DEVICE(0x163E, info) /* ULX */
+
#define INTEL_BDW_RSVD_IDS(info) \
+ INTEL_BDW_ULT_RSVD_IDS(info), \
+ INTEL_BDW_ULX_RSVD_IDS(info), \
INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \
- INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \
- INTEL_VGA_DEVICE(0x163B, info), /* Iris */ \
- INTEL_VGA_DEVICE(0x163E, info), /* ULX */ \
INTEL_VGA_DEVICE(0x163A, info), /* Server */ \
INTEL_VGA_DEVICE(0x163D, info) /* Workstation */
@@ -289,35 +328,53 @@
INTEL_VGA_DEVICE(0x22b2, info), \
INTEL_VGA_DEVICE(0x22b3, info)
-#define INTEL_SKL_GT1_IDS(info) \
+#define INTEL_SKL_ULT_GT1_IDS(info) \
INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \
+ INTEL_VGA_DEVICE(0x1913, info) /* ULT GT1.5 */
+
+#define INTEL_SKL_ULX_GT1_IDS(info) \
INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \
+ INTEL_VGA_DEVICE(0x1915, info) /* ULX GT1.5 */
+
+#define INTEL_SKL_GT1_IDS(info) \
+ INTEL_SKL_ULT_GT1_IDS(info), \
+ INTEL_SKL_ULX_GT1_IDS(info), \
INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \
+ INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */ \
INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \
- INTEL_VGA_DEVICE(0x190A, info) /* SRV GT1 */
+ INTEL_VGA_DEVICE(0x1917, info) /* DT GT1.5 */
-#define INTEL_SKL_GT2_IDS(info) \
+#define INTEL_SKL_ULT_GT2_IDS(info) \
INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \
- INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \
- INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */ \
+ INTEL_VGA_DEVICE(0x1921, info) /* ULT GT2F */
+
+#define INTEL_SKL_ULX_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x191E, info) /* ULX GT2 */
+
+#define INTEL_SKL_GT2_IDS(info) \
+ INTEL_SKL_ULT_GT2_IDS(info), \
+ INTEL_SKL_ULX_GT2_IDS(info), \
INTEL_VGA_DEVICE(0x1912, info), /* DT GT2 */ \
- INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \
INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \
+ INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \
INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */
-#define INTEL_SKL_GT3_IDS(info) \
+#define INTEL_SKL_ULT_GT3_IDS(info) \
INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \
- INTEL_VGA_DEVICE(0x192D, info) /* SRV GT3 */
+ INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3e */ \
+ INTEL_VGA_DEVICE(0x1927, info) /* ULT GT3e */
+
+#define INTEL_SKL_GT3_IDS(info) \
+ INTEL_SKL_ULT_GT3_IDS(info), \
+ INTEL_VGA_DEVICE(0x192A, info), /* SRV GT3 */ \
+ INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3e */ \
+ INTEL_VGA_DEVICE(0x192D, info) /* SRV GT3e */
#define INTEL_SKL_GT4_IDS(info) \
INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \
- INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */ \
- INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \
- INTEL_VGA_DEVICE(0x192A, info), /* SRV GT4 */ \
- INTEL_VGA_DEVICE(0x193A, info) /* SRV GT4e */
+ INTEL_VGA_DEVICE(0x193A, info), /* SRV GT4e */ \
+ INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4e */ \
+ INTEL_VGA_DEVICE(0x193D, info) /* WKS GT4e */
#define INTEL_SKL_IDS(info) \
INTEL_SKL_GT1_IDS(info), \
@@ -336,29 +393,44 @@
INTEL_VGA_DEVICE(0x3184, info), \
INTEL_VGA_DEVICE(0x3185, info)
-#define INTEL_KBL_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \
- INTEL_VGA_DEVICE(0x5915, info), /* ULX GT1.5 */ \
+#define INTEL_KBL_ULT_GT1_IDS(info) \
INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \
+ INTEL_VGA_DEVICE(0x5913, info) /* ULT GT1.5 */
+
+#define INTEL_KBL_ULX_GT1_IDS(info) \
INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \
+ INTEL_VGA_DEVICE(0x5915, info) /* ULX GT1.5 */
+
+#define INTEL_KBL_GT1_IDS(info) \
+ INTEL_KBL_ULT_GT1_IDS(info), \
+ INTEL_KBL_ULX_GT1_IDS(info), \
INTEL_VGA_DEVICE(0x5902, info), /* DT GT1 */ \
INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */ \
- INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */ \
- INTEL_VGA_DEVICE(0x590A, info) /* SRV GT1 */
+ INTEL_VGA_DEVICE(0x590A, info), /* SRV GT1 */ \
+ INTEL_VGA_DEVICE(0x590B, info) /* Halo GT1 */
-#define INTEL_KBL_GT2_IDS(info) \
+#define INTEL_KBL_ULT_GT2_IDS(info) \
INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */ \
- INTEL_VGA_DEVICE(0x5917, info), /* Mobile GT2 */ \
- INTEL_VGA_DEVICE(0x5921, info), /* ULT GT2F */ \
- INTEL_VGA_DEVICE(0x591E, info), /* ULX GT2 */ \
+ INTEL_VGA_DEVICE(0x5921, info) /* ULT GT2F */
+
+#define INTEL_KBL_ULX_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x591E, info) /* ULX GT2 */
+
+#define INTEL_KBL_GT2_IDS(info) \
+ INTEL_KBL_ULT_GT2_IDS(info), \
+ INTEL_KBL_ULX_GT2_IDS(info), \
INTEL_VGA_DEVICE(0x5912, info), /* DT GT2 */ \
- INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \
+ INTEL_VGA_DEVICE(0x5917, info), /* Mobile GT2 */ \
INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */ \
+ INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \
INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */
+#define INTEL_KBL_ULT_GT3_IDS(info) \
+ INTEL_VGA_DEVICE(0x5926, info) /* ULT GT3 */
+
#define INTEL_KBL_GT3_IDS(info) \
+ INTEL_KBL_ULT_GT3_IDS(info), \
INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */ \
INTEL_VGA_DEVICE(0x5927, info) /* ULT GT3 */
#define INTEL_KBL_GT4_IDS(info) \
@@ -375,27 +447,30 @@
/* CML GT1 */
#define INTEL_CML_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x9BA2, info), \
+ INTEL_VGA_DEVICE(0x9BA4, info), \
+ INTEL_VGA_DEVICE(0x9BA5, info), \
+ INTEL_VGA_DEVICE(0x9BA8, info)
+
+#define INTEL_CML_U_GT1_IDS(info) \
INTEL_VGA_DEVICE(0x9B21, info), \
INTEL_VGA_DEVICE(0x9BAA, info), \
- INTEL_VGA_DEVICE(0x9BAB, info), \
- INTEL_VGA_DEVICE(0x9BAC, info), \
- INTEL_VGA_DEVICE(0x9BA0, info), \
- INTEL_VGA_DEVICE(0x9BA5, info), \
- INTEL_VGA_DEVICE(0x9BA8, info), \
- INTEL_VGA_DEVICE(0x9BA4, info), \
- INTEL_VGA_DEVICE(0x9BA2, info)
+ INTEL_VGA_DEVICE(0x9BAC, info)
/* CML GT2 */
#define INTEL_CML_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x9B41, info), \
- INTEL_VGA_DEVICE(0x9BCA, info), \
- INTEL_VGA_DEVICE(0x9BCB, info), \
- INTEL_VGA_DEVICE(0x9BCC, info), \
- INTEL_VGA_DEVICE(0x9BC0, info), \
+ INTEL_VGA_DEVICE(0x9BC2, info), \
+ INTEL_VGA_DEVICE(0x9BC4, info), \
INTEL_VGA_DEVICE(0x9BC5, info), \
+ INTEL_VGA_DEVICE(0x9BC6, info), \
INTEL_VGA_DEVICE(0x9BC8, info), \
- INTEL_VGA_DEVICE(0x9BC4, info), \
- INTEL_VGA_DEVICE(0x9BC2, info)
+ INTEL_VGA_DEVICE(0x9BE6, info), \
+ INTEL_VGA_DEVICE(0x9BF6, info)
+
+#define INTEL_CML_U_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x9B41, info), \
+ INTEL_VGA_DEVICE(0x9BCA, info), \
+ INTEL_VGA_DEVICE(0x9BCC, info)
#define INTEL_KBL_IDS(info) \
INTEL_KBL_GT1_IDS(info), \
@@ -422,8 +497,8 @@
INTEL_VGA_DEVICE(0x3E9C, info)
#define INTEL_CFL_H_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x3E9B, info), /* Halo GT2 */ \
- INTEL_VGA_DEVICE(0x3E94, info) /* Halo GT2 */
+ INTEL_VGA_DEVICE(0x3E94, info), /* Halo GT2 */ \
+ INTEL_VGA_DEVICE(0x3E9B, info) /* Halo GT2 */
/* CFL U GT2 */
#define INTEL_CFL_U_GT2_IDS(info) \
@@ -462,47 +537,112 @@
INTEL_WHL_U_GT3_IDS(info), \
INTEL_AML_CFL_GT2_IDS(info), \
INTEL_CML_GT1_IDS(info), \
- INTEL_CML_GT2_IDS(info)
+ INTEL_CML_GT2_IDS(info), \
+ INTEL_CML_U_GT1_IDS(info), \
+ INTEL_CML_U_GT2_IDS(info)
/* CNL */
+#define INTEL_CNL_PORT_F_IDS(info) \
+ INTEL_VGA_DEVICE(0x5A44, info), \
+ INTEL_VGA_DEVICE(0x5A4C, info), \
+ INTEL_VGA_DEVICE(0x5A54, info), \
+ INTEL_VGA_DEVICE(0x5A5C, info)
+
#define INTEL_CNL_IDS(info) \
- INTEL_VGA_DEVICE(0x5A51, info), \
- INTEL_VGA_DEVICE(0x5A59, info), \
+ INTEL_CNL_PORT_F_IDS(info), \
+ INTEL_VGA_DEVICE(0x5A40, info), \
INTEL_VGA_DEVICE(0x5A41, info), \
- INTEL_VGA_DEVICE(0x5A49, info), \
- INTEL_VGA_DEVICE(0x5A52, info), \
- INTEL_VGA_DEVICE(0x5A5A, info), \
INTEL_VGA_DEVICE(0x5A42, info), \
+ INTEL_VGA_DEVICE(0x5A49, info), \
INTEL_VGA_DEVICE(0x5A4A, info), \
INTEL_VGA_DEVICE(0x5A50, info), \
- INTEL_VGA_DEVICE(0x5A40, info), \
- INTEL_VGA_DEVICE(0x5A54, info), \
- INTEL_VGA_DEVICE(0x5A5C, info), \
- INTEL_VGA_DEVICE(0x5A44, info), \
- INTEL_VGA_DEVICE(0x5A4C, info)
+ INTEL_VGA_DEVICE(0x5A51, info), \
+ INTEL_VGA_DEVICE(0x5A52, info), \
+ INTEL_VGA_DEVICE(0x5A59, info), \
+ INTEL_VGA_DEVICE(0x5A5A, info)
/* ICL */
-#define INTEL_ICL_11_IDS(info) \
+#define INTEL_ICL_PORT_F_IDS(info) \
INTEL_VGA_DEVICE(0x8A50, info), \
- INTEL_VGA_DEVICE(0x8A51, info), \
- INTEL_VGA_DEVICE(0x8A5C, info), \
- INTEL_VGA_DEVICE(0x8A5D, info), \
- INTEL_VGA_DEVICE(0x8A59, info), \
- INTEL_VGA_DEVICE(0x8A58, info), \
INTEL_VGA_DEVICE(0x8A52, info), \
+ INTEL_VGA_DEVICE(0x8A53, info), \
+ INTEL_VGA_DEVICE(0x8A54, info), \
+ INTEL_VGA_DEVICE(0x8A56, info), \
+ INTEL_VGA_DEVICE(0x8A57, info), \
+ INTEL_VGA_DEVICE(0x8A58, info), \
+ INTEL_VGA_DEVICE(0x8A59, info), \
INTEL_VGA_DEVICE(0x8A5A, info), \
INTEL_VGA_DEVICE(0x8A5B, info), \
- INTEL_VGA_DEVICE(0x8A57, info), \
- INTEL_VGA_DEVICE(0x8A56, info), \
- INTEL_VGA_DEVICE(0x8A71, info), \
+ INTEL_VGA_DEVICE(0x8A5C, info), \
INTEL_VGA_DEVICE(0x8A70, info), \
- INTEL_VGA_DEVICE(0x8A53, info)
+ INTEL_VGA_DEVICE(0x8A71, info)
+
+#define INTEL_ICL_11_IDS(info) \
+ INTEL_ICL_PORT_F_IDS(info), \
+ INTEL_VGA_DEVICE(0x8A51, info), \
+ INTEL_VGA_DEVICE(0x8A5D, info)
/* EHL */
#define INTEL_EHL_IDS(info) \
- INTEL_VGA_DEVICE(0x4500, info), \
- INTEL_VGA_DEVICE(0x4571, info), \
+ INTEL_VGA_DEVICE(0x4541, info), \
INTEL_VGA_DEVICE(0x4551, info), \
- INTEL_VGA_DEVICE(0x4541, info)
+ INTEL_VGA_DEVICE(0x4555, info), \
+ INTEL_VGA_DEVICE(0x4557, info), \
+ INTEL_VGA_DEVICE(0x4571, info)
+
+/* JSL */
+#define INTEL_JSL_IDS(info) \
+ INTEL_VGA_DEVICE(0x4E51, info), \
+ INTEL_VGA_DEVICE(0x4E55, info), \
+ INTEL_VGA_DEVICE(0x4E57, info), \
+ INTEL_VGA_DEVICE(0x4E61, info), \
+ INTEL_VGA_DEVICE(0x4E71, info)
+
+/* TGL */
+#define INTEL_TGL_12_GT1_IDS(info) \
+ INTEL_VGA_DEVICE(0x9A60, info), \
+ INTEL_VGA_DEVICE(0x9A68, info), \
+ INTEL_VGA_DEVICE(0x9A70, info)
+
+#define INTEL_TGL_12_GT2_IDS(info) \
+ INTEL_VGA_DEVICE(0x9A40, info), \
+ INTEL_VGA_DEVICE(0x9A49, info), \
+ INTEL_VGA_DEVICE(0x9A59, info), \
+ INTEL_VGA_DEVICE(0x9A78, info), \
+ INTEL_VGA_DEVICE(0x9AC0, info), \
+ INTEL_VGA_DEVICE(0x9AC9, info), \
+ INTEL_VGA_DEVICE(0x9AD9, info), \
+ INTEL_VGA_DEVICE(0x9AF8, info)
+
+#define INTEL_TGL_12_IDS(info) \
+ INTEL_TGL_12_GT1_IDS(info), \
+ INTEL_TGL_12_GT2_IDS(info)
+
+/* RKL */
+#define INTEL_RKL_IDS(info) \
+ INTEL_VGA_DEVICE(0x4C80, info), \
+ INTEL_VGA_DEVICE(0x4C8A, info), \
+ INTEL_VGA_DEVICE(0x4C8B, info), \
+ INTEL_VGA_DEVICE(0x4C8C, info), \
+ INTEL_VGA_DEVICE(0x4C90, info), \
+ INTEL_VGA_DEVICE(0x4C9A, info)
+
+/* DG1 */
+#define INTEL_DG1_IDS(info) \
+ INTEL_VGA_DEVICE(0x4905, info), \
+ INTEL_VGA_DEVICE(0x4906, info), \
+ INTEL_VGA_DEVICE(0x4907, info), \
+ INTEL_VGA_DEVICE(0x4908, info)
+
+/* ADL-S */
+#define INTEL_ADLS_IDS(info) \
+ INTEL_VGA_DEVICE(0x4680, info), \
+ INTEL_VGA_DEVICE(0x4681, info), \
+ INTEL_VGA_DEVICE(0x4682, info), \
+ INTEL_VGA_DEVICE(0x4683, info), \
+ INTEL_VGA_DEVICE(0x4690, info), \
+ INTEL_VGA_DEVICE(0x4691, info), \
+ INTEL_VGA_DEVICE(0x4692, info), \
+ INTEL_VGA_DEVICE(0x4693, info)
#endif /* _I915_PCIIDS_H */
diff --git a/intel/intel-symbol-check b/intel/intel-symbols.txt
index de377bef..132df96a 100755..100644
--- a/intel/intel-symbol-check
+++ b/intel/intel-symbols.txt
@@ -1,17 +1,3 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.sources/LIBDRM_INTEL_H_FILES
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_intel.so} | awk '{print $3}' | while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
drm_intel_bo_alloc
drm_intel_bo_alloc_for_render
drm_intel_bo_alloc_tiled
@@ -95,8 +81,3 @@ drm_intel_get_pooled_eu
drm_intel_get_reset_stats
drm_intel_get_subslice_total
drm_intel_reg_read
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index fbf48730..023af61f 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -1069,6 +1069,28 @@ check_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
tiling_mode, stride, size, flags);
}
+static int get_tiling_mode(drm_intel_bufmgr_gem *bufmgr_gem,
+ uint32_t gem_handle,
+ uint32_t *tiling_mode,
+ uint32_t *swizzle_mode)
+{
+ struct drm_i915_gem_get_tiling get_tiling = {
+ .handle = gem_handle,
+ };
+ int ret;
+
+ ret = drmIoctl(bufmgr_gem->fd,
+ DRM_IOCTL_I915_GEM_GET_TILING,
+ &get_tiling);
+ if (ret != 0 && errno != EOPNOTSUPP)
+ return ret;
+
+ *tiling_mode = get_tiling.tiling_mode;
+ *swizzle_mode = get_tiling.swizzle_mode;
+
+ return 0;
+}
+
/**
* Returns a drm_intel_bo wrapping the given buffer object handle.
*
@@ -1084,7 +1106,6 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
drm_intel_bo_gem *bo_gem;
int ret;
struct drm_gem_open open_arg;
- struct drm_i915_gem_get_tiling get_tiling;
/* At the moment most applications only have a few named bo.
* For instance, in a DRI client only the render buffers passed
@@ -1146,16 +1167,11 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
HASH_ADD(name_hh, bufmgr_gem->name_table,
global_name, sizeof(bo_gem->global_name), bo_gem);
- memclear(get_tiling);
- get_tiling.handle = bo_gem->gem_handle;
- ret = drmIoctl(bufmgr_gem->fd,
- DRM_IOCTL_I915_GEM_GET_TILING,
- &get_tiling);
+ ret = get_tiling_mode(bufmgr_gem, bo_gem->gem_handle,
+ &bo_gem->tiling_mode, &bo_gem->swizzle_mode);
if (ret != 0)
goto err_unref;
- bo_gem->tiling_mode = get_tiling.tiling_mode;
- bo_gem->swizzle_mode = get_tiling.swizzle_mode;
/* XXX stride is unknown */
drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name);
@@ -2634,7 +2650,6 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
int ret;
uint32_t handle;
drm_intel_bo_gem *bo_gem;
- struct drm_i915_gem_get_tiling get_tiling;
pthread_mutex_lock(&bufmgr_gem->lock);
ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle);
@@ -2688,15 +2703,11 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
bo_gem->has_error = false;
bo_gem->reusable = false;
- memclear(get_tiling);
- get_tiling.handle = bo_gem->gem_handle;
- if (drmIoctl(bufmgr_gem->fd,
- DRM_IOCTL_I915_GEM_GET_TILING,
- &get_tiling))
+ ret = get_tiling_mode(bufmgr_gem, handle,
+ &bo_gem->tiling_mode, &bo_gem->swizzle_mode);
+ if (ret)
goto err;
- bo_gem->tiling_mode = get_tiling.tiling_mode;
- bo_gem->swizzle_mode = get_tiling.swizzle_mode;
/* XXX stride is unknown */
drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
@@ -2717,7 +2728,7 @@ drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd)
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
if (drmPrimeHandleToFD(bufmgr_gem->fd, bo_gem->gem_handle,
- DRM_CLOEXEC, prime_fd) != 0)
+ DRM_CLOEXEC | DRM_RDWR, prime_fd) != 0)
return -errno;
bo_gem->reusable = false;
diff --git a/intel/intel_chipset.c b/intel/intel_chipset.c
index 5aa4a2f2..fda3de1a 100644
--- a/intel/intel_chipset.c
+++ b/intel/intel_chipset.c
@@ -35,6 +35,12 @@ static const struct pci_device {
uint16_t gen;
} pciids[] = {
/* Keep ids sorted by gen; latest gen first */
+ INTEL_ADLS_IDS(12),
+ INTEL_RKL_IDS(12),
+ INTEL_DG1_IDS(12),
+ INTEL_TGL_12_IDS(12),
+ INTEL_JSL_IDS(11),
+ INTEL_EHL_IDS(11),
INTEL_ICL_11_IDS(11),
INTEL_CNL_IDS(10),
INTEL_CFL_IDS(9),
diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
index 5db207cc..0a48e0da 100644
--- a/intel/intel_chipset.h
+++ b/intel/intel_chipset.h
@@ -337,6 +337,7 @@ drm_private bool intel_get_genx(unsigned int devid, int *gen);
#define IS_GEN9(devid) intel_is_genx(devid, 9)
#define IS_GEN10(devid) intel_is_genx(devid, 10)
#define IS_GEN11(devid) intel_is_genx(devid, 11)
+#define IS_GEN12(devid) intel_is_genx(devid, 12)
#define IS_9XX(dev) (IS_GEN3(dev) || \
IS_GEN4(dev) || \
diff --git a/intel/meson.build b/intel/meson.build
index 3d6bbac6..4d3f1ebd 100644
--- a/intel/meson.build
+++ b/intel/meson.build
@@ -64,43 +64,41 @@ test_decode = executable(
test(
'gen4-3d.batch',
- prog_bash,
- args : files('tests/gen4-3d.batch.sh'),
+ find_program('tests/gen4-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen45-3d.batch',
- prog_bash,
- args : files('tests/gm45-3d.batch.sh'),
+ find_program('tests/gm45-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen5-3d.batch',
- prog_bash,
- args : files('tests/gen5-3d.batch.sh'),
+ find_program('tests/gen5-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen6-3d.batch',
- prog_bash,
- args : files('tests/gen6-3d.batch.sh'),
+ find_program('tests/gen6-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen7-3d.batch',
- prog_bash,
- args : files('tests/gen7-3d.batch.sh'),
+ find_program('tests/gen7-3d.batch.sh'),
workdir : meson.current_build_dir(),
)
test(
'gen7-2d-copy.batch',
- prog_bash,
- args : files('tests/gen7-2d-copy.batch.sh'),
+ find_program('tests/gen7-2d-copy.batch.sh'),
workdir : meson.current_build_dir(),
)
+
test(
- 'intel-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('intel-symbol-check'), libdrm_intel]
+ 'intel-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_intel,
+ '--symbols-file', files('intel-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/intel/tests/test-batch.sh b/intel/tests/test-batch.sh
index a94057ff..b85f639a 100755
--- a/intel/tests/test-batch.sh
+++ b/intel/tests/test-batch.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-TEST_FILENAME=`echo "$0" | sed 's|.sh||'`
+TEST_FILENAME=`echo "$0" | sed 's|\.sh$||'`
./test_decode $TEST_FILENAME
ret=$?
diff --git a/libkms/Android.bp b/libkms/Android.bp
index b09dbf42..d46bab4f 100644
--- a/libkms/Android.bp
+++ b/libkms/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_shared {
diff --git a/libkms/Makefile.am b/libkms/Makefile.am
deleted file mode 100644
index ff4c1b2a..00000000
--- a/libkms/Makefile.am
+++ /dev/null
@@ -1,45 +0,0 @@
-include Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)
-
-libkms_la_LTLIBRARIES = libkms.la
-libkms_ladir = $(libdir)
-libkms_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libkms_la_LIBADD = ../libdrm.la
-
-libkms_la_SOURCES = $(LIBKMS_FILES)
-
-if HAVE_VMWGFX
-libkms_la_SOURCES += $(LIBKMS_VMWGFX_FILES)
-endif
-
-if HAVE_INTEL
-libkms_la_SOURCES += $(LIBKMS_INTEL_FILES)
-endif
-
-if HAVE_NOUVEAU
-libkms_la_SOURCES += $(LIBKMS_NOUVEAU_FILES)
-endif
-
-if HAVE_RADEON
-libkms_la_SOURCES += $(LIBKMS_RADEON_FILES)
-endif
-
-if HAVE_EXYNOS
-libkms_la_SOURCES += $(LIBKMS_EXYNOS_FILES)
-AM_CFLAGS += -I$(top_srcdir)/exynos
-endif
-
-libkmsincludedir = ${includedir}/libkms
-libkmsinclude_HEADERS = $(LIBKMS_H_FILES)
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libkms.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = kms-symbol-check
-EXTRA_DIST = $(TESTS)
diff --git a/libkms/kms-symbol-check b/libkms/kms-symbol-check
deleted file mode 100755
index 30f444f7..00000000
--- a/libkms/kms-symbol-check
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.sources/LIBKMS_H_FILES
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libkms.so} | awk '{print $3}'| while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
-kms_bo_create
-kms_bo_destroy
-kms_bo_get_prop
-kms_bo_map
-kms_bo_unmap
-kms_create
-kms_destroy
-kms_get_prop
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/libkms/kms-symbols.txt b/libkms/kms-symbols.txt
new file mode 100644
index 00000000..e0ba8c91
--- /dev/null
+++ b/libkms/kms-symbols.txt
@@ -0,0 +1,8 @@
+kms_bo_create
+kms_bo_destroy
+kms_bo_get_prop
+kms_bo_map
+kms_bo_unmap
+kms_create
+kms_destroy
+kms_get_prop
diff --git a/libkms/meson.build b/libkms/meson.build
index dc931608..216be4df 100644
--- a/libkms/meson.build
+++ b/libkms/meson.build
@@ -68,8 +68,11 @@ pkg.generate(
)
test(
- 'kms-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('kms-symbol-check'), libkms]
+ 'kms-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libkms,
+ '--symbols-file', files('kms-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/m4/.gitignore b/m4/.gitignore
deleted file mode 100644
index 464ba5ca..00000000
--- a/m4/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-libtool.m4
-lt~obsolete.m4
-ltoptions.m4
-ltsugar.m4
-ltversion.m4
diff --git a/man/Makefile.am b/man/Makefile.am
deleted file mode 100644
index 00eb4234..00000000
--- a/man/Makefile.am
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# This generates man-pages out of the Docbook XML files. Simply add your files
-# to the relevant *man_PRE array. If aliases are created, please add them to the
-# *man_aliases_PRE array so they get installed correctly.
-#
-
-libman_PRE = \
- drmAvailable.xml \
- drmHandleEvent.xml \
- drmModeGetResources.xml
-
-miscman_PRE = \
- drm.xml \
- drm-kms.xml \
- drm-memory.xml
-
-miscman_aliases_PRE = \
- drm-mm.xml \
- drm-gem.xml \
- drm-ttm.xml
-
-libmandir = $(LIB_MAN_DIR)
-miscmandir = $(MISC_MAN_DIR)
-miscman_aliasesdir = $(MISC_MAN_DIR)
-
-libman_DATA = $(libman_PRE:.xml=.$(LIB_MAN_SUFFIX))
-miscman_DATA = $(miscman_PRE:.xml=.$(MISC_MAN_SUFFIX))
-miscman_aliases_DATA = $(miscman_aliases_PRE:.xml=.$(MISC_MAN_SUFFIX))
-
-XML_FILES = \
- $(libman_PRE) \
- $(miscman_PRE)
-
-MAN_FILES = \
- $(libman_DATA) \
- $(miscman_DATA) \
- $(miscman_aliases_DATA)
-
-EXTRA_DIST = $(XML_FILES)
-CLEANFILES = $(MAN_FILES)
-
-XSLTPROC_FLAGS = \
- --stringparam man.authors.section.enabled 0 \
- --stringparam man.copyright.section.enabled 0 \
- --stringparam funcsynopsis.style ansi \
- --stringparam man.output.quietly 1 \
- --nonet \
- $(MANPAGES_STYLESHEET)
-
-XSLTPROC_PROCESS_MAN = \
- $(AM_V_GEN)$(XSLTPROC) -o "$@" $(XSLTPROC_FLAGS) "$<"
-
-$(miscman_aliases_DATA): $(miscman_DATA)
- $(AM_V_GEN)if test -n "$@" ; then $(SED) -i -e 's/^\.so \([a-z_]\+\)\.\([0-9]\)$$/\.so man\2\/\1\.\2/' "$@" ; fi
-
-SUFFIXES = .$(LIB_MAN_SUFFIX) .$(MISC_MAN_SUFFIX) .xml
-
-.xml.$(LIB_MAN_SUFFIX):
- $(XSLTPROC_PROCESS_MAN)
-
-.xml.$(MISC_MAN_SUFFIX):
- $(XSLTPROC_PROCESS_MAN)
diff --git a/man/drm-kms.7.rst b/man/drm-kms.7.rst
new file mode 100644
index 00000000..e91fbe27
--- /dev/null
+++ b/man/drm-kms.7.rst
@@ -0,0 +1,229 @@
+=======
+drm-kms
+=======
+
+-------------------
+Kernel Mode-Setting
+-------------------
+
+:Date: September 2012
+:Manual section: 7
+:Manual group: Direct Rendering Manager
+
+Synopsis
+========
+
+``#include <xf86drm.h>``
+
+``#include <xf86drmMode.h>``
+
+Description
+===========
+
+Each DRM device provides access to manage which monitors and displays are
+currently used and what frames to be displayed. This task is called *Kernel
+Mode-Setting* (KMS). Historically, this was done in user-space and called
+*User-space Mode-Setting* (UMS). Almost all open-source drivers now provide the
+KMS kernel API to do this in the kernel, however, many non-open-source binary
+drivers from different vendors still do not support this. You can use
+**drmModeSettingSupported**\ (3) to check whether your driver supports this. To
+understand how KMS works, we need to introduce 5 objects: *CRTCs*, *Planes*,
+*Encoders*, *Connectors* and *Framebuffers*.
+
+CRTCs
+ A *CRTC* short for *CRT Controller* is an abstraction representing a part of
+ the chip that contains a pointer to a scanout buffer. Therefore, the number
+ of CRTCs available determines how many independent scanout buffers can be
+ active at any given time. The CRTC structure contains several fields to
+ support this: a pointer to some video memory (abstracted as a frame-buffer
+ object), a list of driven connectors, a display mode and an (x, y) offset
+ into the video memory to support panning or configurations where one piece
+ of video memory spans multiple CRTCs. A CRTC is the central point where
+ configuration of displays happens. You select which objects to use, which
+ modes and which parameters and then configure each CRTC via
+ **drmModeCrtcSet**\ (3) to drive the display devices.
+
+Planes
+ A *plane* respresents an image source that can be blended with or overlayed
+ on top of a CRTC during the scanout process. Planes are associated with a
+ frame-buffer to crop a portion of the image memory (source) and optionally
+ scale it to a destination size. The result is then blended with or overlayed
+ on top of a CRTC. Planes are not provided by all hardware and the number of
+ available planes is limited. If planes are not available or if not enough
+ planes are available, the user should fall back to normal software blending
+ (via GPU or CPU).
+
+Encoders
+ An *encoder* takes pixel data from a CRTC and converts it to a format
+ suitable for any attached connectors. On some devices, it may be possible to
+ have a CRTC send data to more than one encoder. In that case, both encoders
+ would receive data from the same scanout buffer, resulting in a *cloned*
+ display configuration across the connectors attached to each encoder.
+
+Connectors
+ A *connector* is the final destination of pixel-data on a device, and
+ usually connects directly to an external display device like a monitor or
+ laptop panel. A connector can only be attached to one encoder at a time. The
+ connector is also the structure where information about the attached display
+ is kept, so it contains fields for display data, *EDID* data, *DPMS* and
+ *connection status*, and information about modes supported on the attached
+ displays.
+
+Framebuffers
+ *Framebuffers* are abstract memory objects that provide a source of pixel
+ data to scanout to a CRTC. Applications explicitly request the creation of
+ framebuffers and can control their behavior. Framebuffers rely on the
+ underneath memory manager for low-level memory operations. When creating a
+ framebuffer, applications pass a memory handle through the API which is used
+ as backing storage. The framebuffer itself is only an abstract object with
+ no data. It just refers to memory buffers that must be created with the
+ **drm-memory**\ (7) API.
+
+Mode-Setting
+------------
+
+Before mode-setting can be performed, an application needs to call
+**drmSetMaster**\ (3) to become *DRM-Master*. It then has exclusive access to
+the KMS API. A call to **drmModeGetResources**\ (3) returns a list of *CRTCs*,
+*Connectors*, *Encoders* and *Planes*.
+
+Normal procedure now includes: First, you select which connectors you want to
+use. Users are mostly interested in which monitor or display-panel is active so
+you need to make sure to arrange them in the correct logical order and select
+the correct ones to use. For each connector, you need to find a CRTC to drive
+this connector. If you want to clone output to two or more connectors, you may
+use a single CRTC for all cloned connectors (if the hardware supports this). To
+find a suitable CRTC, you need to iterate over the list of encoders that are
+available for each connector. Each encoder contains a list of CRTCs that it can
+work with and you simply select one of these CRTCs. If you later program the
+CRTC to control a connector, it automatically selects the best encoder.
+However, this procedure is needed so your CRTC has at least one working encoder
+for the selected connector. See the *Examples* section below for more
+information.
+
+All valid modes for a connector can be retrieved with a call to
+drmModeGetConnector3 You need to select the mode you want to use and save it.
+The first mode in the list is the default mode with the highest resolution
+possible and often a suitable choice.
+
+After you have a working connector+CRTC+mode combination, you need to create a
+framebuffer that is used for scanout. Memory buffer allocation is
+driver-depedent and described in **drm-memory**\ (7). You need to create a
+buffer big enough for your selected mode. Now you can create a framebuffer
+object that uses your memory-buffer as scanout buffer. You can do this with
+**drmModeAddFB**\ (3) and **drmModeAddFB2**\ (3).
+
+As a last step, you want to program your CRTC to drive your selected connector.
+You can do this with a call to **drmModeSetCrtc**\ (3).
+
+Page-Flipping
+-------------
+
+A call to **drmModeSetCrtc**\ (3) is executed immediately and forces the CRTC
+to use the new scanout buffer. If you want smooth-transitions without tearing,
+you probably use double-buffering. You need to create one framebuffer object
+for each buffer you use. You can then call **drmModeSetCrtc**\ (3) on the next
+buffer to flip. If you want to synchronize your flips with *vertical-blanks*,
+you can use **drmModePageFlip**\ (3) which schedules your page-flip for the
+next *vblank*.
+
+Planes
+------
+
+Planes are controlled independently from CRTCs. That is, a call to
+**drmModeSetCrtc**\ (3) does not affect planes. Instead, you need to call
+**drmModeSetPlane**\ (3) to configure a plane. This requires the plane ID, a
+CRTC, a framebuffer and offsets into the plane-framebuffer and the
+CRTC-framebuffer. The CRTC then blends the content from the plane over the CRTC
+framebuffer buffer during scanout. As this does not involve any
+software-blending, it is way faster than traditional blending. However, plane
+resources are limited. See **drmModeGetPlaneResources**\ (3) for more
+information.
+
+Cursors
+-------
+
+Similar to planes, many hardware also supports cursors. A cursor is a very
+small buffer with an image that is blended over the CRTC framebuffer. You can
+set a different cursor for each CRTC with **drmModeSetCursor**\ (3) and move it
+on the screen with **drmModeMoveCursor**\ (3). This allows to move the cursor
+on the screen without rerendering. If no hardware cursors are supported, you
+need to rerender for each frame the cursor is moved.
+
+Examples
+========
+
+Some examples of how basic mode-setting can be done. See the man-page of each
+DRM function for more information.
+
+CRTC/Encoder Selection
+----------------------
+
+If you retrieved all display configuration information via
+**drmModeGetResources**\ (3) as ``drmModeRes *res``, selected a connector from
+the list in ``res->connectors`` and retrieved the connector-information as
+``drmModeConnector *conn`` via **drmModeGetConnector**\ (3) then this example
+shows, how you can find a suitable CRTC id to drive this connector. This
+function takes a file-descriptor to the DRM device (see **drmOpen**\ (3)) as
+``fd``, a pointer to the retrieved resources as ``res`` and a pointer to the
+selected connector as ``conn``. It returns an integer smaller than 0 on
+failure, otherwise, a valid CRTC id is returned.
+
+::
+
+ static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn)
+ {
+ drmModeEncoder *enc;
+ unsigned int i, j;
+
+ /* iterate all encoders of this connector */
+ for (i = 0; i < conn->count_encoders; ++i) {
+ enc = drmModeGetEncoder(fd, conn->encoders[i]);
+ if (!enc) {
+ /* cannot retrieve encoder, ignoring... */
+ continue;
+ }
+
+ /* iterate all global CRTCs */
+ for (j = 0; j < res->count_crtcs; ++j) {
+ /* check whether this CRTC works with the encoder */
+ if (!(enc->possible_crtcs & (1 << j)))
+ continue;
+
+
+ /* Here you need to check that no other connector
+ * currently uses the CRTC with id "crtc". If you intend
+ * to drive one connector only, then you can skip this
+ * step. Otherwise, simply scan your list of configured
+ * connectors and CRTCs whether this CRTC is already
+ * used. If it is, then simply continue the search here. */
+ if (res->crtcs[j] "is unused") {
+ drmModeFreeEncoder(enc);
+ return res->crtcs[j];
+ }
+ }
+
+ drmModeFreeEncoder(enc);
+ }
+
+ /* cannot find a suitable CRTC */
+ return -ENOENT;
+ }
+
+Reporting Bugs
+==============
+
+Bugs in this manual should be reported to
+https://gitlab.freedesktop.org/mesa/drm/-/issues
+
+See Also
+========
+
+**drm**\ (7), **drm-memory**\ (7), **drmModeGetResources**\ (3),
+**drmModeGetConnector**\ (3), **drmModeGetEncoder**\ (3),
+**drmModeGetCrtc**\ (3), **drmModeSetCrtc**\ (3), **drmModeGetFB**\ (3),
+**drmModeAddFB**\ (3), **drmModeAddFB2**\ (3), **drmModeRmFB**\ (3),
+**drmModePageFlip**\ (3), **drmModeGetPlaneResources**\ (3),
+**drmModeGetPlane**\ (3), **drmModeSetPlane**\ (3), **drmModeSetCursor**\ (3),
+**drmModeMoveCursor**\ (3), **drmSetMaster**\ (3), **drmAvailable**\ (3),
+**drmCheckModesettingSupported**\ (3), **drmOpen**\ (3)
diff --git a/man/drm-kms.xml b/man/drm-kms.xml
deleted file mode 100644
index eb04c263..00000000
--- a/man/drm-kms.xml
+++ /dev/null
@@ -1,342 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
- Dedicated to the Public Domain
--->
-
-<refentry id="drm-kms">
- <refentryinfo>
- <title>Direct Rendering Manager</title>
- <productname>libdrm</productname>
- <date>September 2012</date>
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>David</firstname>
- <surname>Herrmann</surname>
- <email>dh.herrmann@googlemail.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>drm-kms</refentrytitle>
- <manvolnum>7</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>drm-kms</refname>
- <refpurpose>Kernel Mode-Setting</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <funcsynopsis>
- <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
- <funcsynopsisinfo>#include &lt;xf86drmMode.h&gt;</funcsynopsisinfo>
- </funcsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
- <para>Each DRM device provides access to manage which monitors and displays
- are currently used and what frames to be displayed. This task is
- called <emphasis>Kernel Mode-Setting</emphasis> (KMS). Historically,
- this was done in user-space and called
- <emphasis>User-space Mode-Setting</emphasis> (UMS). Almost all
- open-source drivers now provide the KMS kernel API to do this in the
- kernel, however, many non-open-source binary drivers from different
- vendors still do not support this. You can use
- <citerefentry><refentrytitle>drmModeSettingSupported</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- to check whether your driver supports this. To understand how KMS
- works, we need to introduce 5 objects: <emphasis>CRTCs</emphasis>,
- <emphasis>Planes</emphasis>, <emphasis>Encoders</emphasis>,
- <emphasis>Connectors</emphasis> and
- <emphasis>Framebuffers</emphasis>.
-
- <variablelist>
- <varlistentry>
- <term>CRTCs</term>
- <listitem>
- <para>A <emphasis>CRTC</emphasis> short for
- <emphasis>CRT Controller</emphasis> is an abstraction
- representing a part of the chip that contains a pointer to a
- scanout buffer. Therefore, the number of CRTCs available
- determines how many independent scanout buffers can be active
- at any given time. The CRTC structure contains several fields
- to support this: a pointer to some video memory (abstracted as
- a frame-buffer object), a list of driven connectors, a display
- mode and an (x, y) offset into the video memory to support
- panning or configurations where one piece of video memory
- spans multiple CRTCs. A CRTC is the central point where
- configuration of displays happens. You select which objects to
- use, which modes and which parameters and then configure each
- CRTC via
- <citerefentry><refentrytitle>drmModeCrtcSet</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- to drive the display devices.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Planes</term>
- <listitem>
- <para>A <emphasis>plane</emphasis> respresents an image source that
- can be blended with or overlayed on top of a CRTC during the
- scanout process. Planes are associated with a frame-buffer to
- crop a portion of the image memory (source) and optionally
- scale it to a destination size. The result is then blended
- with or overlayed on top of a CRTC. Planes are not provided by
- all hardware and the number of available planes is limited. If
- planes are not available or if not enough planes are
- available, the user should fall back to normal software
- blending (via GPU or CPU).</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Encoders</term>
- <listitem>
- <para>An <emphasis>encoder</emphasis> takes pixel data from a CRTC
- and converts it to a format suitable for any attached
- connectors. On some devices, it may be possible to have a CRTC
- send data to more than one encoder. In that case, both
- encoders would receive data from the same scanout buffer,
- resulting in a <emphasis>cloned</emphasis> display
- configuration across the connectors attached to each
- encoder.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Connectors</term>
- <listitem>
- <para>A <emphasis>connector</emphasis> is the final destination of
- pixel-data on a device, and usually connects directly to an
- external display device like a monitor or laptop panel. A
- connector can only be attached to one encoder at a time. The
- connector is also the structure where information about the
- attached display is kept, so it contains fields for display
- data, <emphasis>EDID</emphasis> data,
- <emphasis>DPMS</emphasis> and
- <emphasis>connection status</emphasis>, and information about
- modes supported on the attached displays.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Framebuffers</term>
- <listitem>
- <para><emphasis>Framebuffers</emphasis> are abstract memory objects
- that provide a source of pixel data to scanout to a CRTC.
- Applications explicitly request the creation of framebuffers
- and can control their behavior. Framebuffers rely on the
- underneath memory manager for low-level memory operations.
- When creating a framebuffer, applications pass a memory handle
- through the API which is used as backing storage. The
- framebuffer itself is only an abstract object with no data. It
- just refers to memory buffers that must be created with the
- <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- API.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </para>
-
- <refsect2>
- <title>Mode-Setting</title>
- <para>Before mode-setting can be performed, an application needs to call
- <citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- to become <emphasis>DRM-Master</emphasis>. It then has exclusive
- access to the KMS API. A call to
- <citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- returns a list of <emphasis>CRTCs</emphasis>,
- <emphasis>Connectors</emphasis>, <emphasis>Encoders</emphasis> and
- <emphasis>Planes</emphasis>.</para>
-
- <para>Normal procedure now includes: First, you select which connectors
- you want to use. Users are mostly interested in which monitor or
- display-panel is active so you need to make sure to arrange them in
- the correct logical order and select the correct ones to use. For
- each connector, you need to find a CRTC to drive this connector. If
- you want to clone output to two or more connectors, you may use a
- single CRTC for all cloned connectors (if the hardware supports
- this). To find a suitable CRTC, you need to iterate over the list of
- encoders that are available for each connector. Each encoder
- contains a list of CRTCs that it can work with and you simply select
- one of these CRTCs. If you later program the CRTC to control a
- connector, it automatically selects the best encoder. However, this
- procedure is needed so your CRTC has at least one working encoder
- for the selected connector. See the <emphasis>Examples</emphasis>
- section below for more information.</para>
-
- <para>All valid modes for a connector can be retrieved with a call to
- <citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- You need to select the mode you want to use and save it. The first
- mode in the list is the default mode with the highest resolution
- possible and often a suitable choice.</para>
-
- <para>After you have a working connector+CRTC+mode combination, you need
- to create a framebuffer that is used for scanout. Memory buffer
- allocation is driver-depedent and described in
- <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
- You need to create a buffer big enough for your selected mode. Now
- you can create a framebuffer object that uses your memory-buffer as
- scanout buffer. You can do this with
- <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- and
- <citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
-
- <para>As a last step, you want to program your CRTC to drive your selected
- connector. You can do this with a call to
- <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
- </refsect2>
-
- <refsect2>
- <title>Page-Flipping</title>
- <para>A call to
- <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- is executed immediately and forces the CRTC to use the new scanout
- buffer. If you want smooth-transitions without tearing, you probably
- use double-buffering. You need to create one framebuffer object for
- each buffer you use. You can then call
- <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- on the next buffer to flip. If you want to synchronize your flips
- with <emphasis>vertical-blanks</emphasis>, you can use
- <citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- which schedules your page-flip for the next
- <emphasis>vblank</emphasis>.</para>
- </refsect2>
-
- <refsect2>
- <title>Planes</title>
- <para>Planes are controlled independently from CRTCs. That is, a call to
- <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- does not affect planes. Instead, you need to call
- <citerefentry><refentrytitle>drmModeSetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- to configure a plane. This requires the plane ID, a CRTC, a
- framebuffer and offsets into the plane-framebuffer and the
- CRTC-framebuffer. The CRTC then blends the content from the plane
- over the CRTC framebuffer buffer during scanout. As this does not
- involve any software-blending, it is way faster than traditional
- blending. However, plane resources are limited. See
- <citerefentry><refentrytitle>drmModeGetPlaneResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- for more information.</para>
- </refsect2>
-
- <refsect2>
- <title>Cursors</title>
- <para>Similar to planes, many hardware also supports cursors. A cursor is
- a very small buffer with an image that is blended over the CRTC
- framebuffer. You can set a different cursor for each CRTC with
- <citerefentry><refentrytitle>drmModeSetCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- and move it on the screen with
- <citerefentry><refentrytitle>drmModeMoveCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
- This allows to move the cursor on the screen without rerendering. If
- no hardware cursors are supported, you need to rerender for each
- frame the cursor is moved.</para>
- </refsect2>
-
- </refsect1>
-
- <refsect1>
- <title>Examples</title>
- <para>Some examples of how basic mode-setting can be done. See the man-page
- of each DRM function for more information.</para>
-
- <refsect2>
- <title>CRTC/Encoder Selection</title>
- <para>If you retrieved all display configuration information via
- <citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- as <structname>drmModeRes</structname> *<varname>res</varname>,
- selected a connector from the list in
- <varname>res</varname>-><structfield>connectors</structfield>
- and retrieved the connector-information as
- <structname>drmModeConnector</structname> *<varname>conn</varname>
- via
- <citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- then this example shows, how you can find a suitable CRTC id to
- drive this connector. This function takes a file-descriptor to the
- DRM device (see
- <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>)
- as <varname>fd</varname>, a pointer to the retrieved resources as
- <varname>res</varname> and a pointer to the selected connector as
- <varname>conn</varname>. It returns an integer smaller than 0 on
- failure, otherwise, a valid CRTC id is returned.</para>
-
-<programlisting>
-static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn)
-{
- drmModeEncoder *enc;
- unsigned int i, j;
-
- /* iterate all encoders of this connector */
- for (i = 0; i &lt; conn->count_encoders; ++i) {
- enc = drmModeGetEncoder(fd, conn->encoders[i]);
- if (!enc) {
- /* cannot retrieve encoder, ignoring... */
- continue;
- }
-
- /* iterate all global CRTCs */
- for (j = 0; j &lt; res->count_crtcs; ++j) {
- /* check whether this CRTC works with the encoder */
- if (!(enc->possible_crtcs &amp; (1 &lt;&lt; j)))
- continue;
-
-
- /* Here you need to check that no other connector
- * currently uses the CRTC with id "crtc". If you intend
- * to drive one connector only, then you can skip this
- * step. Otherwise, simply scan your list of configured
- * connectors and CRTCs whether this CRTC is already
- * used. If it is, then simply continue the search here. */
- if (res->crtcs[j] "is unused") {
- drmModeFreeEncoder(enc);
- return res->crtcs[j];
- }
- }
-
- drmModeFreeEncoder(enc);
- }
-
- /* cannot find a suitable CRTC */
- return -ENOENT;
-}
-</programlisting>
-
- </refsect2>
-
- </refsect1>
-
- <refsect1>
- <title>Reporting Bugs</title>
- <para>Bugs in this manual should be reported to
- https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
- under the "DRI" product, component "libdrm"</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetEncoder</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeRmFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetPlaneResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeSetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeSetCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeMoveCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmCheckModesettingSupported</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- </para>
- </refsect1>
-</refentry>
diff --git a/man/drm-memory.7.rst b/man/drm-memory.7.rst
new file mode 100644
index 00000000..c272c994
--- /dev/null
+++ b/man/drm-memory.7.rst
@@ -0,0 +1,322 @@
+==========
+drm-memory
+==========
+
+---------------------
+DRM Memory Management
+---------------------
+
+:Date: September 2012
+:Manual section: 7
+:Manual group: Direct Rendering Manager
+
+Synopsis
+========
+
+``#include <xf86drm.h>``
+
+Description
+===========
+
+Many modern high-end GPUs come with their own memory managers. They even
+include several different caches that need to be synchronized during access.
+Textures, framebuffers, command buffers and more need to be stored in memory
+that can be accessed quickly by the GPU. Therefore, memory management on GPUs
+is highly driver- and hardware-dependent.
+
+However, there are several frameworks in the kernel that are used by more than
+one driver. These can be used for trivial mode-setting without requiring
+driver-dependent code. But for hardware-accelerated rendering you need to read
+the manual pages for the driver you want to work with.
+
+Dumb-Buffers
+------------
+
+Almost all in-kernel DRM hardware drivers support an API called *Dumb-Buffers*.
+This API allows to create buffers of arbitrary size that can be used for
+scanout. These buffers can be memory mapped via **mmap**\ (2) so you can render
+into them on the CPU. However, GPU access to these buffers is often not
+possible. Therefore, they are fine for simple tasks but not suitable for
+complex compositions and renderings.
+
+The ``DRM_IOCTL_MODE_CREATE_DUMB`` ioctl can be used to create a dumb buffer.
+The kernel will return a 32-bit handle that can be used to manage the buffer
+with the DRM API. You can create framebuffers with **drmModeAddFB**\ (3) and
+use it for mode-setting and scanout. To access the buffer, you first need to
+retrieve the offset of the buffer. The ``DRM_IOCTL_MODE_MAP_DUMB`` ioctl
+requests the DRM subsystem to prepare the buffer for memory-mapping and returns
+a fake-offset that can be used with **mmap**\ (2).
+
+The ``DRM_IOCTL_MODE_CREATE_DUMB`` ioctl takes as argument a structure of type
+``struct drm_mode_create_dumb``:
+
+::
+
+ struct drm_mode_create_dumb {
+ __u32 height;
+ __u32 width;
+ __u32 bpp;
+ __u32 flags;
+
+ __u32 handle;
+ __u32 pitch;
+ __u64 size;
+ };
+
+The fields *height*, *width*, *bpp* and *flags* have to be provided by the
+caller. The other fields are filled by the kernel with the return values.
+*height* and *width* are the dimensions of the rectangular buffer that is
+created. *bpp* is the number of bits-per-pixel and must be a multiple of 8. You
+most commonly want to pass 32 here. The flags field is currently unused and
+must be zeroed. Different flags to modify the behavior may be added in the
+future. After calling the ioctl, the handle, pitch and size fields are filled
+by the kernel. *handle* is a 32-bit gem handle that identifies the buffer. This
+is used by several other calls that take a gem-handle or memory-buffer as
+argument. The *pitch* field is the pitch (or stride) of the new buffer. Most
+drivers use 32-bit or 64-bit aligned stride-values. The size field contains the
+absolute size in bytes of the buffer. This can normally also be computed with
+``(height * pitch + width) * bpp / 4``.
+
+To prepare the buffer for **mmap**\ (2) you need to use the
+``DRM_IOCTL_MODE_MAP_DUMB`` ioctl. It takes as argument a structure of type
+``struct drm_mode_map_dumb``:
+
+::
+
+ struct drm_mode_map_dumb {
+ __u32 handle;
+ __u32 pad;
+
+ __u64 offset;
+ };
+
+You need to put the gem-handle that was previously retrieved via
+``DRM_IOCTL_MODE_CREATE_DUMB`` into the *handle* field. The *pad* field is
+unused padding and must be zeroed. After completion, the *offset* field will
+contain an offset that can be used with **mmap**\ (2) on the DRM
+file-descriptor.
+
+If you don't need your dumb-buffer, anymore, you have to destroy it with
+``DRM_IOCTL_MODE_DESTROY_DUMB``. If you close the DRM file-descriptor, all open
+dumb-buffers are automatically destroyed. This ioctl takes as argument a
+structure of type ``struct drm_mode_destroy_dumb``:
+
+::
+
+ struct drm_mode_destroy_dumb {
+ __u32 handle;
+ };
+
+You only need to put your handle into the *handle* field. After this call, the
+handle is invalid and may be reused for new buffers by the dumb-API.
+
+TTM
+---
+
+*TTM* stands for *Translation Table Manager* and is a generic memory-manager
+provided by the kernel. It does not provide a common user-space API so you need
+to look at each driver interface if you want to use it. See for instance the
+radeon man pages for more information on memory-management with radeon and TTM.
+
+GEM
+---
+
+*GEM* stands for *Graphics Execution Manager* and is a generic DRM
+memory-management framework in the kernel, that is used by many different
+drivers. GEM is designed to manage graphics memory, control access to the
+graphics device execution context and handle essentially NUMA environment
+unique to modern graphics hardware. GEM allows multiple applications to share
+graphics device resources without the need to constantly reload the entire
+graphics card. Data may be shared between multiple applications with gem
+ensuring that the correct memory synchronization occurs.
+
+GEM provides simple mechanisms to manage graphics data and control execution
+flow within the linux DRM subsystem. However, GEM is not a complete framework
+that is fully driver independent. Instead, if provides many functions that are
+shared between many drivers, but each driver has to implement most of
+memory-management with driver-dependent ioctls. This manpage tries to describe
+the semantics (and if it applies, the syntax) that is shared between all
+drivers that use GEM.
+
+All GEM APIs are defined as **ioctl**\ (2) on the DRM file descriptor. An
+application must be authorized via **drmAuthMagic**\ (3) to the current
+DRM-Master to access the GEM subsystem. A driver that does not support GEM will
+return ``ENODEV`` for all these ioctls. Invalid object handles return
+``EINVAL`` and invalid object names return ``ENOENT``.
+
+Gem provides explicit memory management primitives. System pages are allocated
+when the object is created, either as the fundamental storage for hardware
+where system memory is used by the graphics processor directly, or as backing
+store for graphics-processor resident memory.
+
+Objects are referenced from user-space using handles. These are, for all
+intents and purposes, equivalent to file descriptors but avoid the overhead.
+Newer kernel drivers also support the **drm-prime** (7) infrastructure which
+can return real file-descriptor for GEM-handles using the linux DMA-BUF API.
+Objects may be published with a name so that other applications and processes
+can access them. The name remains valid as long as the object exists.
+GEM-objects are reference counted in the kernel. The object is only destroyed
+when all handles from user-space were closed.
+
+GEM-buffers cannot be created with a generic API. Each driver provides its own
+API to create GEM-buffers. See for example ``DRM_I915_GEM_CREATE``,
+``DRM_NOUVEAU_GEM_NEW`` or ``DRM_RADEON_GEM_CREATE``. Each of these ioctls
+returns a GEM-handle that can be passed to different generic ioctls. The
+*libgbm* library from the *mesa3D* distribution tries to provide a
+driver-independent API to create GBM buffers and retrieve a GBM-handle to them.
+It allows to create buffers for different use-cases including scanout,
+rendering, cursors and CPU-access. See the libgbm library for more information
+or look at the driver-dependent man-pages (for example **drm-intel**\ (7) or
+**drm-radeon**\ (7)).
+
+GEM-buffers can be closed with the ``DRM_IOCTL_GEM_CLOSE`` ioctl. It takes as
+argument a structure of type ``struct drm_gem_close``:
+
+::
+
+ struct drm_gem_close {
+ __u32 handle;
+ __u32 pad;
+ };
+
+The *handle* field is the GEM-handle to be closed. The *pad* field is unused
+padding. It must be zeroed. After this call the GEM handle cannot be used by
+this process anymore and may be reused for new GEM objects by the GEM API.
+
+If you want to share GEM-objects between different processes, you can create a
+name for them and pass this name to other processes which can then open this
+GEM-object. Names are currently 32-bit integer IDs and have no special
+protection. That is, if you put a name on your GEM-object, every other client
+that has access to the DRM device and is authenticated via
+**drmAuthMagic**\ (3) to the current DRM-Master, can *guess* the name and open
+or access the GEM-object. If you want more fine-grained access control, you can
+use the new **drm-prime**\ (7) API to retrieve file-descriptors for
+GEM-handles. To create a name for a GEM-handle, you use the
+``DRM_IOCTL_GEM_FLINK`` ioctl. It takes as argument a structure of type
+``struct drm_gem_flink``:
+
+::
+
+ struct drm_gem_flink {
+ __u32 handle;
+ __u32 name;
+ };
+
+You have to put your handle into the *handle* field. After completion, the
+kernel has put the new unique name into the name field. You can now pass
+this name to other processes which can then import the name with the
+``DRM_IOCTL_GEM_OPEN`` ioctl. It takes as argument a structure of type
+``struct drm_gem_open``:
+
+::
+
+ struct drm_gem_open {
+ __u32 name;
+
+ __u32 handle;
+ __u32 size;
+ };
+
+You have to fill in the *name* field with the name of the GEM-object that you
+want to open. The kernel will fill in the *handle* and *size* fields with the
+new handle and size of the GEM-object. You can now access the GEM-object via
+the handle as if you created it with the GEM API.
+
+Besides generic buffer management, the GEM API does not provide any generic
+access. Each driver implements its own functionality on top of this API. This
+includes execution-buffers, GTT management, context creation, CPU access, GPU
+I/O and more. The next higher-level API is *OpenGL*. So if you want to use more
+GPU features, you should use the *mesa3D* library to create OpenGL contexts on
+DRM devices. This does *not* require any windowing-system like X11, but can
+also be done on raw DRM devices. However, this is beyond the scope of this
+man-page. You may have a look at other mesa3D man pages, including libgbm and
+libEGL. 2D software-rendering (rendering with the CPU) can be achieved with the
+dumb-buffer-API in a driver-independent fashion, however, for
+hardware-accelerated 2D or 3D rendering you must use OpenGL. Any other API that
+tries to abstract the driver-internals to access GEM-execution-buffers and
+other GPU internals, would simply reinvent OpenGL so it is not provided. But if
+you need more detailed information for a specific driver, you may have a look
+into the driver-manpages, including **drm-intel**\ (7), **drm-radeon**\ (7) and
+**drm-nouveau**\ (7). However, the **drm-prime**\ (7) infrastructure and the
+generic GEM API as described here allow display-managers to handle
+graphics-buffers and render-clients without any deeper knowledge of the GPU
+that is used. Moreover, it allows to move objects between GPUs and implement
+complex display-servers that don't do any rendering on their own. See its
+man-page for more information.
+
+Examples
+========
+
+This section includes examples for basic memory-management tasks.
+
+Dumb-Buffers
+------------
+
+This examples shows how to create a dumb-buffer via the generic DRM API.
+This is driver-independent (as long as the driver supports dumb-buffers)
+and provides memory-mapped buffers that can be used for scanout. This
+example creates a full-HD 1920x1080 buffer with 32 bits-per-pixel and a
+color-depth of 24 bits. The buffer is then bound to a framebuffer which
+can be used for scanout with the KMS API (see **drm-kms**\ (7)).
+
+::
+
+ struct drm_mode_create_dumb creq;
+ struct drm_mode_destroy_dumb dreq;
+ struct drm_mode_map_dumb mreq;
+ uint32_t fb;
+ int ret;
+ void *map;
+
+ /* create dumb buffer */
+ memset(&creq, 0, sizeof(creq));
+ creq.width = 1920;
+ creq.height = 1080;
+ creq.bpp = 32;
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
+ if (ret < 0) {
+ /* buffer creation failed; see "errno" for more error codes */
+ ...
+ }
+ /* creq.pitch, creq.handle and creq.size are filled by this ioctl with
+ * the requested values and can be used now. */
+
+ /* create framebuffer object for the dumb-buffer */
+ ret = drmModeAddFB(fd, 1920, 1080, 24, 32, creq.pitch, creq.handle, &fb);
+ if (ret) {
+ /* frame buffer creation failed; see "errno" */
+ ...
+ }
+ /* the framebuffer "fb" can now used for scanout with KMS */
+
+ /* prepare buffer for memory mapping */
+ memset(&mreq, 0, sizeof(mreq));
+ mreq.handle = creq.handle;
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
+ if (ret) {
+ /* DRM buffer preparation failed; see "errno" */
+ ...
+ }
+ /* mreq.offset now contains the new offset that can be used with mmap() */
+
+ /* perform actual memory mapping */
+ map = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
+ if (map == MAP_FAILED) {
+ /* memory-mapping failed; see "errno" */
+ ...
+ }
+
+ /* clear the framebuffer to 0 */
+ memset(map, 0, creq.size);
+
+Reporting Bugs
+==============
+
+Bugs in this manual should be reported to
+https://gitlab.freedesktop.org/mesa/drm/-/issues
+
+See Also
+========
+
+**drm**\ (7), **drm-kms**\ (7), **drm-prime**\ (7), **drmAvailable**\ (3),
+**drmOpen**\ (3), **drm-intel**\ (7), **drm-radeon**\ (7), **drm-nouveau**\ (7)
diff --git a/man/drm-memory.xml b/man/drm-memory.xml
deleted file mode 100644
index 3aa7cf25..00000000
--- a/man/drm-memory.xml
+++ /dev/null
@@ -1,430 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
- Dedicated to the Public Domain
--->
-
-<refentry id="drm-memory">
- <refentryinfo>
- <title>Direct Rendering Manager</title>
- <productname>libdrm</productname>
- <date>September 2012</date>
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>David</firstname>
- <surname>Herrmann</surname>
- <email>dh.herrmann@googlemail.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>drm-memory</refentrytitle>
- <manvolnum>7</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>drm-memory</refname>
- <refname>drm-mm</refname>
- <refname>drm-gem</refname>
- <refname>drm-ttm</refname>
- <refpurpose>DRM Memory Management</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <funcsynopsis>
- <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
- </funcsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
- <para>Many modern high-end GPUs come with their own memory managers. They
- even include several different caches that need to be synchronized
- during access. Textures, framebuffers, command buffers and more need
- to be stored in memory that can be accessed quickly by the GPU.
- Therefore, memory management on GPUs is highly driver- and
- hardware-dependent.</para>
-
- <para>However, there are several frameworks in the kernel that are used by
- more than one driver. These can be used for trivial mode-setting
- without requiring driver-dependent code. But for
- hardware-accelerated rendering you need to read the manual pages for
- the driver you want to work with.</para>
-
- <refsect2>
- <title>Dumb-Buffers</title>
- <para>Almost all in-kernel DRM hardware drivers support an API called
- <emphasis>Dumb-Buffers</emphasis>. This API allows to create buffers
- of arbitrary size that can be used for scanout. These buffers can be
- memory mapped via
- <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- so you can render into them on the CPU. However, GPU access to these
- buffers is often not possible. Therefore, they are fine for simple
- tasks but not suitable for complex compositions and
- renderings.</para>
-
- <para>The <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> ioctl can be
- used to create a dumb buffer. The kernel will return a 32bit handle
- that can be used to manage the buffer with the DRM API. You can
- create framebuffers with
- <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- and use it for mode-setting and scanout. To access the buffer, you
- first need to retrieve the offset of the buffer. The
- <constant>DRM_IOCTL_MODE_MAP_DUMB</constant> ioctl requests the DRM
- subsystem to prepare the buffer for memory-mapping and returns a
- fake-offset that can be used with
- <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
-
- <para>The <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> ioctl takes as
- argument a structure of type
- <structname>struct drm_mode_create_dumb</structname>:
-
-<programlisting>
-struct drm_mode_create_dumb {
- __u32 height;
- __u32 width;
- __u32 bpp;
- __u32 flags;
-
- __u32 handle;
- __u32 pitch;
- __u64 size;
-};
-</programlisting>
-
- The fields <structfield>height</structfield>,
- <structfield>width</structfield>, <structfield>bpp</structfield> and
- <structfield>flags</structfield> have to be provided by the caller.
- The other fields are filled by the kernel with the return values.
- <structfield>height</structfield> and
- <structfield>width</structfield> are the dimensions of the
- rectangular buffer that is created. <structfield>bpp</structfield>
- is the number of bits-per-pixel and must be a multiple of
- <literal>8</literal>. You most commonly want to pass
- <literal>32</literal> here. The <structfield>flags</structfield>
- field is currently unused and must be zeroed. Different flags to
- modify the behavior may be added in the future. After calling the
- ioctl, the <structfield>handle</structfield>,
- <structfield>pitch</structfield> and <structfield>size</structfield>
- fields are filled by the kernel. <structfield>handle</structfield>
- is a 32bit gem handle that identifies the buffer. This is used by
- several other calls that take a gem-handle or memory-buffer as
- argument. The <structfield>pitch</structfield> field is the
- pitch (or stride) of the new buffer. Most drivers use 32bit or 64bit
- aligned stride-values. The <structfield>size</structfield> field
- contains the absolute size in bytes of the buffer. This can normally
- also be computed with
- <emphasis>(height * pitch + width) * bpp / 4</emphasis>.</para>
-
- <para>To prepare the buffer for
- <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- you need to use the <constant>DRM_IOCTL_MODE_MAP_DUMB</constant>
- ioctl. It takes as argument a structure of type
- <structname>struct drm_mode_map_dumb</structname>:
-
-<programlisting>
-struct drm_mode_map_dumb {
- __u32 handle;
- __u32 pad;
-
- __u64 offset;
-};
-</programlisting>
-
- You need to put the gem-handle that was previously retrieved via
- <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> into the
- <structfield>handle</structfield> field. The
- <structfield>pad</structfield> field is unused padding and must be
- zeroed. After completion, the <structfield>offset</structfield>
- field will contain an offset that can be used with
- <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- on the DRM file-descriptor.</para>
-
- <para>If you don't need your dumb-buffer, anymore, you have to destroy it
- with <constant>DRM_IOCTL_MODE_DESTROY_DUMB</constant>. If you close
- the DRM file-descriptor, all open dumb-buffers are automatically
- destroyed. This ioctl takes as argument a structure of type
- <structname>struct drm_mode_destroy_dumb</structname>:
-
-<programlisting>
-struct drm_mode_destroy_dumb {
- __u32 handle;
-};
-</programlisting>
-
- You only need to put your handle into the
- <structfield>handle</structfield> field. After this call, the handle
- is invalid and may be reused for new buffers by the dumb-API.</para>
-
- </refsect2>
-
- <refsect2>
- <title>TTM</title>
- <para><emphasis>TTM</emphasis> stands for
- <emphasis>Translation Table Manager</emphasis> and is a generic
- memory-manager provided by the kernel. It does not provide a common
- user-space API so you need to look at each driver interface if you
- want to use it. See for instance the radeon manpages for more
- information on memory-management with radeon and TTM.</para>
- </refsect2>
-
- <refsect2>
- <title>GEM</title>
- <para><emphasis>GEM</emphasis> stands for
- <emphasis>Graphics Execution Manager</emphasis> and is a generic DRM
- memory-management framework in the kernel, that is used by many
- different drivers. Gem is designed to manage graphics memory,
- control access to the graphics device execution context and handle
- essentially NUMA environment unique to modern graphics hardware. Gem
- allows multiple applications to share graphics device resources
- without the need to constantly reload the entire graphics card. Data
- may be shared between multiple applications with gem ensuring that
- the correct memory synchronization occurs.</para>
-
- <para>Gem provides simple mechanisms to manage graphics data and control
- execution flow within the linux DRM subsystem. However, gem is not a
- complete framework that is fully driver independent. Instead, if
- provides many functions that are shared between many drivers, but
- each driver has to implement most of memory-management with
- driver-dependent ioctls. This manpage tries to describe the
- semantics (and if it applies, the syntax) that is shared between all
- drivers that use gem.</para>
-
- <para>All GEM APIs are defined as
- <citerefentry><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- on the DRM file descriptor. An application must be authorized via
- <citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- to the current DRM-Master to access the GEM subsystem. A driver that
- does not support gem will return <constant>ENODEV</constant> for all
- these ioctls. Invalid object handles return
- <constant>EINVAL</constant> and invalid object names return
- <constant>ENOENT</constant>.</para>
-
- <para>Gem provides explicit memory management primitives. System pages are
- allocated when the object is created, either as the fundamental
- storage for hardware where system memory is used by the graphics
- processor directly, or as backing store for graphics-processor
- resident memory.</para>
-
- <para>Objects are referenced from user-space using handles. These are, for
- all intents and purposes, equivalent to file descriptors but avoid
- the overhead. Newer kernel drivers also support the
- <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- infrastructure which can return real file-descriptor for gem-handles
- using the linux dma-buf API. Objects may be published with a name so
- that other applications and processes can access them. The name
- remains valid as long as the object exists. Gem-objects are
- reference counted in the kernel. The object is only destroyed when
- all handles from user-space were closed.</para>
-
- <para>Gem-buffers cannot be created with a generic API. Each driver
- provides its own API to create gem-buffers. See for example
- <constant>DRM_I915_GEM_CREATE</constant>,
- <constant>DRM_NOUVEAU_GEM_NEW</constant> or
- <constant>DRM_RADEON_GEM_CREATE</constant>. Each of these ioctls
- returns a gem-handle that can be passed to different generic ioctls.
- The <emphasis>libgbm</emphasis> library from the
- <emphasis>mesa3D</emphasis> distribution tries to provide a
- driver-independent API to create gbm buffers and retrieve a
- gbm-handle to them. It allows to create buffers for different
- use-cases including scanout, rendering, cursors and CPU-access. See
- the libgbm library for more information or look at the
- driver-dependent man-pages (for example
- <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- or
- <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>).</para>
-
- <para>Gem-buffers can be closed with the
- <constant>DRM_IOCTL_GEM_CLOSE</constant> ioctl. It takes as argument
- a structure of type <structname>struct drm_gem_close</structname>:
-
-<programlisting>
-struct drm_gem_close {
- __u32 handle;
- __u32 pad;
-};
-</programlisting>
-
- The <structfield>handle</structfield> field is the gem-handle to be
- closed. The <structfield>pad</structfield> field is unused padding.
- It must be zeroed. After this call the gem handle cannot be used by
- this process anymore and may be reused for new gem objects by the
- gem API.</para>
-
- <para>If you want to share gem-objects between different processes, you
- can create a name for them and pass this name to other processes
- which can then open this gem-object. Names are currently 32bit
- integer IDs and have no special protection. That is, if you put a
- name on your gem-object, every other client that has access to the
- DRM device and is authenticated via
- <citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- to the current DRM-Master, can <emphasis>guess</emphasis> the name
- and open or access the gem-object. If you want more fine-grained
- access control, you can use the new
- <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- API to retrieve file-descriptors for gem-handles. To create a name
- for a gem-handle, you use the
- <constant>DRM_IOCTL_GEM_FLINK</constant> ioctl. It takes as argument
- a structure of type <structname>struct drm_gem_flink</structname>:
-
-<programlisting>
-struct drm_gem_flink {
- __u32 handle;
- __u32 name;
-};
-</programlisting>
-
- You have to put your handle into the
- <structfield>handle</structfield> field. After completion, the
- kernel has put the new unique name into the
- <structfield>name</structfield> field. You can now pass this name to
- other processes which can then import the name with the
- <constant>DRM_IOCTL_GEM_OPEN</constant> ioctl. It takes as argument
- a structure of type <structname>struct drm_gem_open</structname>:
-
-<programlisting>
-struct drm_gem_open {
- __u32 name;
-
- __u32 handle;
- __u32 size;
-};
-</programlisting>
-
- You have to fill in the <structfield>name</structfield> field with
- the name of the gem-object that you want to open. The kernel will
- fill in the <structfield>handle</structfield> and
- <structfield>size</structfield> fields with the new handle and size
- of the gem-object. You can now access the gem-object via the handle
- as if you created it with the gem API.</para>
-
- <para>Besides generic buffer management, the GEM API does not provide any
- generic access. Each driver implements its own functionality on top
- of this API. This includes execution-buffers, GTT management,
- context creation, CPU access, GPU I/O and more. The next
- higher-level API is <emphasis>OpenGL</emphasis>. So if you want to
- use more GPU features, you should use the
- <emphasis>mesa3D</emphasis> library to create OpenGL contexts on DRM
- devices. This does <emphasis>not</emphasis> require any
- windowing-system like X11, but can also be done on raw DRM devices.
- However, this is beyond the scope of this man-page. You may have a
- look at other mesa3D manpages, including libgbm and libEGL. 2D
- software-rendering (rendering with the CPU) can be achieved with the
- dumb-buffer-API in a driver-independent fashion, however, for
- hardware-accelerated 2D or 3D rendering you must use OpenGL. Any
- other API that tries to abstract the driver-internals to access
- GEM-execution-buffers and other GPU internals, would simply reinvent
- OpenGL so it is not provided. But if you need more detailed
- information for a specific driver, you may have a look into the
- driver-manpages, including
- <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- and
- <citerefentry><refentrytitle>drm-nouveau</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
- However, the
- <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- infrastructure and the generic gem API as described here allow
- display-managers to handle graphics-buffers and render-clients
- without any deeper knowledge of the GPU that is used. Moreover, it
- allows to move objects between GPUs and implement complex
- display-servers that don't do any rendering on their own. See its
- man-page for more information.</para>
- </refsect2>
- </refsect1>
-
- <refsect1>
- <title>Examples</title>
- <para>This section includes examples for basic memory-management
- tasks.</para>
-
- <refsect2>
- <title>Dumb-Buffers</title>
- <para>This examples shows how to create a dumb-buffer via the generic
- DRM API. This is driver-independent (as long as the driver
- supports dumb-buffers) and provides memory-mapped buffers that can
- be used for scanout. This example creates a full-HD 1920x1080
- buffer with 32 bits-per-pixel and a color-depth of 24 bits. The
- buffer is then bound to a framebuffer which can be used for
- scanout with the KMS API (see
- <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>).</para>
-
-<programlisting>
-struct drm_mode_create_dumb creq;
-struct drm_mode_destroy_dumb dreq;
-struct drm_mode_map_dumb mreq;
-uint32_t fb;
-int ret;
-void *map;
-
-/* create dumb buffer */
-memset(&amp;creq, 0, sizeof(creq));
-creq.width = 1920;
-creq.height = 1080;
-creq.bpp = 32;
-ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &amp;creq);
-if (ret &lt; 0) {
- /* buffer creation failed; see "errno" for more error codes */
- ...
-}
-/* creq.pitch, creq.handle and creq.size are filled by this ioctl with
- * the requested values and can be used now. */
-
-/* create framebuffer object for the dumb-buffer */
-ret = drmModeAddFB(fd, 1920, 1080, 24, 32, creq.pitch, creq.handle, &amp;fb);
-if (ret) {
- /* frame buffer creation failed; see "errno" */
- ...
-}
-/* the framebuffer "fb" can now used for scanout with KMS */
-
-/* prepare buffer for memory mapping */
-memset(&amp;mreq, 0, sizeof(mreq));
-mreq.handle = creq.handle;
-ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &amp;mreq);
-if (ret) {
- /* DRM buffer preparation failed; see "errno" */
- ...
-}
-/* mreq.offset now contains the new offset that can be used with mmap() */
-
-/* perform actual memory mapping */
-map = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
-if (map == MAP_FAILED) {
- /* memory-mapping failed; see "errno" */
- ...
-}
-
-/* clear the framebuffer to 0 */
-memset(map, 0, creq.size);
-</programlisting>
-
- </refsect2>
-
- </refsect1>
-
- <refsect1>
- <title>Reporting Bugs</title>
- <para>Bugs in this manual should be reported to
- https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
- under the "DRI" product, component "libdrm"</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-nouveau</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- </para>
- </refsect1>
-</refentry>
diff --git a/man/drm.7.rst b/man/drm.7.rst
new file mode 100644
index 00000000..c9b5696f
--- /dev/null
+++ b/man/drm.7.rst
@@ -0,0 +1,91 @@
+===
+drm
+===
+
+------------------------
+Direct Rendering Manager
+------------------------
+
+:Date: September 2012
+:Manual section: 7
+:Manual group: Direct Rendering Manager
+
+Synopsis
+========
+
+``#include <xf86drm.h>``
+
+Description
+===========
+
+The *Direct Rendering Manager* (DRM) is a framework to manage *Graphics
+Processing Units* (GPUs). It is designed to support the needs of complex
+graphics devices, usually containing programmable pipelines well suited
+to 3D graphics acceleration. Furthermore, it is responsible for memory
+management, interrupt handling and DMA to provide a uniform interface to
+applications.
+
+In earlier days, the kernel framework was solely used to provide raw
+hardware access to privileged user-space processes which implement all
+the hardware abstraction layers. But more and more tasks were moved into
+the kernel. All these interfaces are based on **ioctl**\ (2) commands on
+the DRM character device. The *libdrm* library provides wrappers for these
+system-calls and many helpers to simplify the API.
+
+When a GPU is detected, the DRM system loads a driver for the detected
+hardware type. Each connected GPU is then presented to user-space via a
+character-device that is usually available as ``/dev/dri/card0`` and can
+be accessed with **open**\ (2) and **close**\ (2). However, it still
+depends on the graphics driver which interfaces are available on these
+devices. If an interface is not available, the syscalls will fail with
+``EINVAL``.
+
+Authentication
+--------------
+
+All DRM devices provide authentication mechanisms. Only a DRM master is
+allowed to perform mode-setting or modify core state and only one user
+can be DRM master at a time. See **drmSetMaster**\ (3) for information
+on how to become DRM master and what the limitations are. Other DRM users
+can be authenticated to the DRM-Master via **drmAuthMagic**\ (3) so they
+can perform buffer allocations and rendering.
+
+Mode-Setting
+------------
+
+Managing connected monitors and displays and changing the current modes
+is called *Mode-Setting*. This is restricted to the current DRM master.
+Historically, this was implemented in user-space, but new DRM drivers
+implement a kernel interface to perform mode-setting called *Kernel Mode
+Setting* (KMS). If your hardware-driver supports it, you can use the KMS
+API provided by DRM. This includes allocating framebuffers, selecting
+modes and managing CRTCs and encoders. See **drm-kms**\ (7) for more.
+
+Memory Management
+-----------------
+
+The most sophisticated tasks for GPUs today is managing memory objects.
+Textures, framebuffers, command-buffers and all other kinds of commands
+for the GPU have to be stored in memory. The DRM driver takes care of
+managing all memory objects, flushing caches, synchronizing access and
+providing CPU access to GPU memory. All memory management is hardware
+driver dependent. However, two generic frameworks are available that are
+used by most DRM drivers. These are the *Translation Table Manager*
+(TTM) and the *Graphics Execution Manager* (GEM). They provide generic
+APIs to create, destroy and access buffers from user-space. However,
+there are still many differences between the drivers so driver-depedent
+code is still needed. Many helpers are provided in *libgbm* (Graphics
+Buffer Manager) from the *Mesa* project. For more information on DRM
+memory management, see **drm-memory**\ (7).
+
+Reporting Bugs
+==============
+
+Bugs in this manual should be reported to
+https://gitlab.freedesktop.org/mesa/drm/-/issues.
+
+See Also
+========
+
+**drm-kms**\ (7), **drm-memory**\ (7), **drmSetMaster**\ (3),
+**drmAuthMagic**\ (3), **drmAvailable**\ (3), **drmOpen**\ (3)
diff --git a/man/drm.xml b/man/drm.xml
deleted file mode 100644
index dbb67adc..00000000
--- a/man/drm.xml
+++ /dev/null
@@ -1,137 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
- Dedicated to the Public Domain
--->
-
-<refentry id="drm">
- <refentryinfo>
- <title>Direct Rendering Manager</title>
- <productname>libdrm</productname>
- <date>September 2012</date>
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>David</firstname>
- <surname>Herrmann</surname>
- <email>dh.herrmann@googlemail.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>drm</refentrytitle>
- <manvolnum>7</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>drm</refname>
- <refpurpose>Direct Rendering Manager</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <funcsynopsis>
- <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
- </funcsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
- <para>The <emphasis>Direct Rendering Manager</emphasis> (DRM) is a framework
- to manage <emphasis>Graphics Processing Units</emphasis> (GPUs). It is
- designed to support the needs of complex graphics devices, usually
- containing programmable pipelines well suited to 3D graphics
- acceleration. Furthermore, it is responsible for memory management,
- interrupt handling and DMA to provide a uniform interface to
- applications.</para>
-
- <para>In earlier days, the kernel framework was solely used to provide raw
- hardware access to privileged user-space processes which implement
- all the hardware abstraction layers. But more and more tasks were
- moved into the kernel. All these interfaces are based on
- <citerefentry><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- commands on the DRM character device. The <emphasis>libdrm</emphasis>
- library provides wrappers for these system-calls and many helpers to
- simplify the API.</para>
-
- <para>When a GPU is detected, the DRM system loads a driver for the detected
- hardware type. Each connected GPU is then presented to user-space via
- a character-device that is usually available as
- <filename>/dev/dri/card0</filename> and can be accessed with
- <citerefentry><refentrytitle>open</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- and
- <citerefentry><refentrytitle>close</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
- However, it still depends on the graphics driver which interfaces are
- available on these devices. If an interface is not available, the
- syscalls will fail with <literal>EINVAL</literal>.</para>
-
- <refsect2>
- <title>Authentication</title>
- <para>All DRM devices provide authentication mechanisms. Only a DRM-Master
- is allowed to perform mode-setting or modify core state and only one
- user can be DRM-Master at a time. See
- <citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- for information on how to become DRM-Master and what the limitations
- are. Other DRM users can be authenticated to the DRM-Master via
- <citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- so they can perform buffer allocations and rendering.</para>
- </refsect2>
-
- <refsect2>
- <title>Mode-Setting</title>
- <para>Managing connected monitors and displays and changing the current
- modes is called <emphasis>Mode-Setting</emphasis>. This is
- restricted to the current DRM-Master. Historically, this was
- implemented in user-space, but new DRM drivers implement a kernel
- interface to perform mode-setting called
- <emphasis>Kernel Mode Setting</emphasis> (KMS). If your
- hardware-driver supports it, you can use the KMS API provided by
- DRM. This includes allocating framebuffers, selecting modes and
- managing CRTCs and encoders. See
- <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- for more.</para>
- </refsect2>
-
- <refsect2>
- <title>Memory Management</title>
- <para>The most sophisticated tasks for GPUs today is managing memory
- objects. Textures, framebuffers, command-buffers and all other kinds
- of commands for the GPU have to be stored in memory. The DRM driver
- takes care of managing all memory objects, flushing caches,
- synchronizing access and providing CPU access to GPU memory. All
- memory management is hardware driver dependent. However, two generic
- frameworks are available that are used by most DRM drivers. These
- are the <emphasis>Translation Table Manager</emphasis> (TTM) and the
- <emphasis>Graphics Execution Manager</emphasis> (GEM). They provide
- generic APIs to create, destroy and access buffers from user-space.
- However, there are still many differences between the drivers so
- driver-depedent code is still needed. Many helpers are provided in
- <emphasis>libgbm</emphasis> (Graphics Buffer Manager) from the
- <emphasis>mesa-project</emphasis>. For more information on DRM
- memory-management, see
- <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
- </refsect2>
- </refsect1>
-
- <refsect1>
- <title>Reporting Bugs</title>
- <para>Bugs in this manual should be reported to
- https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
- under the "DRI" product, component "libdrm"</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- </para>
- </refsect1>
-</refentry>
diff --git a/man/drmAvailable.3.rst b/man/drmAvailable.3.rst
new file mode 100644
index 00000000..5da77beb
--- /dev/null
+++ b/man/drmAvailable.3.rst
@@ -0,0 +1,41 @@
+============
+drmAvailable
+============
+
+-----------------------------------------------------
+determine whether a DRM kernel driver has been loaded
+-----------------------------------------------------
+
+:Date: September 2012
+:Manual section: 3
+:Manual group: Direct Rendering Manager
+
+Synopsis
+========
+
+``#include <xf86drm.h>``
+
+``int drmAvailable(void);``
+
+Description
+===========
+
+``drmAvailable`` allows the caller to determine whether a kernel DRM
+driver is loaded.
+
+Return Value
+============
+
+``drmAvailable`` returns 1 if a DRM driver is currently loaded.
+Otherwise 0 is returned.
+
+Reporting Bugs
+==============
+
+Bugs in this function should be reported to
+https://gitlab.freedesktop.org/mesa/drm/-/issues
+
+See Also
+========
+
+**drm**\ (7), **drmOpen**\ (3)
diff --git a/man/drmAvailable.xml b/man/drmAvailable.xml
deleted file mode 100644
index 1e5d7873..00000000
--- a/man/drmAvailable.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
- Dedicated to the Public Domain
--->
-
-<refentry id="drmAvailable">
- <refentryinfo>
- <title>Direct Rendering Manager</title>
- <productname>libdrm</productname>
- <date>September 2012</date>
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>David</firstname>
- <surname>Herrmann</surname>
- <email>dh.herrmann@googlemail.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>drmAvailable</refentrytitle>
- <manvolnum>3</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>drmAvailable</refname>
- <refpurpose>determine whether a DRM kernel driver has been
- loaded</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <funcsynopsis>
-
- <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
-
- <funcprototype>
- <funcdef>int <function>drmAvailable</function></funcdef>
- <paramdef>void</paramdef>
- </funcprototype>
-
- </funcsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
- <para><function>drmAvailable</function> allows the caller to determine
- whether a kernel DRM driver is loaded.</para>
- </refsect1>
-
- <refsect1>
- <title>Return Value</title>
- <para><function>drmAvailable</function> returns 1 if a DRM driver is
- currently loaded. Otherwise 0 is returned.</para>
- </refsect1>
-
- <refsect1>
- <title>Reporting Bugs</title>
- <para>Bugs in this function should be reported to
- https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
- under the "DRI" product, component "libdrm"</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- </para>
- </refsect1>
-</refentry>
diff --git a/man/drmHandleEvent.3.rst b/man/drmHandleEvent.3.rst
new file mode 100644
index 00000000..ecc63ed0
--- /dev/null
+++ b/man/drmHandleEvent.3.rst
@@ -0,0 +1,62 @@
+==============
+drmHandleEvent
+==============
+
+-----------------------------------
+read and process pending DRM events
+-----------------------------------
+
+:Date: September 2012
+:Manual section: 3
+:Manual group: Direct Rendering Manager
+
+Synopsis
+========
+
+``#include <xf86drm.h>``
+
+``int drmHandleEvent(int fd, drmEventContextPtr evctx);``
+
+Description
+===========
+
+``drmHandleEvent`` processes outstanding DRM events on the DRM
+file-descriptor passed as ``fd``. This function should be called after
+the DRM file-descriptor has polled readable; it will read the events and
+use the passed-in ``evctx`` structure to call function pointers with the
+parameters noted below:
+
+::
+
+ typedef struct _drmEventContext {
+ int version;
+ void (*vblank_handler) (int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data)
+ void (*page_flip_handler) (int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data)
+ } drmEventContext, *drmEventContextPtr;
+
+Return Value
+============
+
+``drmHandleEvent`` returns 0 on success, or if there is no data to
+read from the file-descriptor. Returns -1 if the read on the
+file-descriptor fails or returns less than a full event record.
+
+Reporting Bugs
+==============
+
+Bugs in this function should be reported to
+https://gitlab.freedesktop.org/mesa/drm/-/issues
+
+See Also
+========
+
+**drm**\ (7), **drm-kms**\ (7), **drmModePageFlip**\ (3),
+**drmWaitVBlank**\ (3)
diff --git a/man/drmHandleEvent.xml b/man/drmHandleEvent.xml
deleted file mode 100644
index 83304428..00000000
--- a/man/drmHandleEvent.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
- Dedicated to the Public Domain
--->
-
-<refentry id="drmHandleEvent">
- <refentryinfo>
- <title>Direct Rendering Manager</title>
- <productname>libdrm</productname>
- <date>September 2012</date>
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>David</firstname>
- <surname>Herrmann</surname>
- <email>dh.herrmann@googlemail.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>drmHandleEvent</refentrytitle>
- <manvolnum>3</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>drmHandleEvent</refname>
- <refpurpose>read and process pending DRM events</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
-
- <funcsynopsis>
- <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
-
- <funcprototype>
- <funcdef>int <function>drmHandleEvent</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- <paramdef>drmEventContextPtr <parameter>evctx</parameter></paramdef>
- </funcprototype>
- </funcsynopsis>
-
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
- <para><function>drmHandleEvent</function> processes outstanding DRM events
- on the DRM file-descriptor passed as <parameter>fd</parameter>. This
- function should be called after the DRM file-descriptor has polled
- readable; it will read the events and use the passed-in
- <parameter>evctx</parameter> structure to call function pointers
- with the parameters noted below:
-
-<programlisting>
-typedef struct _drmEventContext {
- int version;
- void (*vblank_handler) (int fd,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- void *user_data)
- void (*page_flip_handler) (int fd,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- void *user_data)
-} drmEventContext, *drmEventContextPtr;
-</programlisting>
-
- </para>
-
- </refsect1>
-
- <refsect1>
- <title>Return Value</title>
- <para><function>drmHandleEvent</function> returns <literal>0</literal> on
- success, or if there is no data to read from the file-descriptor.
- Returns <literal>-1</literal> if the read on the file-descriptor fails
- or returns less than a full event record.</para>
- </refsect1>
-
- <refsect1>
- <title>Reporting Bugs</title>
- <para>Bugs in this function should be reported to
- https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
- under the "DRI" product, component "libdrm"</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmWaitVBlank</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- </para>
- </refsect1>
-</refentry>
diff --git a/man/drmModeGetResources.3.rst b/man/drmModeGetResources.3.rst
new file mode 100644
index 00000000..d1358d22
--- /dev/null
+++ b/man/drmModeGetResources.3.rst
@@ -0,0 +1,92 @@
+===================
+drmModeGetResources
+===================
+
+--------------------------------------------------
+retrieve current display configuration information
+--------------------------------------------------
+
+:Date: September 2012
+:Manual section: 3
+:Manual group: Direct Rendering Manager
+
+Synopsis
+========
+
+``#include <xf86drm.h>``
+
+``#include <xf86drmMode.h>``
+
+``drmModeResPtr drmModeGetResources(int fd);``
+
+Description
+===========
+
+``drmModeGetResources`` allocates, populates, and returns a drmModeRes
+structure containing information about the current display
+configuration. The structure contains the following fields:
+
+::
+
+ typedef struct _drmModeRes {
+ int count_fbs;
+ uint32_t *fbs;
+
+ int count_crtcs;
+ uint32_t *crtcs;
+
+ int count_connectors;
+ uint32_t *connectors;
+
+ int count_encoders;
+ uint32_t *encoders;
+
+ uint32_t min_width, max_width;
+ uint32_t min_height, max_height;
+ } drmModeRes, *drmModeResPtr;
+
+The *count_fbs* and *fbs* fields indicate the number of currently allocated
+framebuffer objects (i.e., objects that can be attached to a given CRTC
+or sprite for display).
+
+The *count_crtcs* and *crtcs* fields list the available CRTCs in the
+configuration. A CRTC is simply an object that can scan out a
+framebuffer to a display sink, and contains mode timing and relative
+position information. CRTCs drive encoders, which are responsible for
+converting the pixel stream into a specific display protocol (e.g., MIPI
+or HDMI).
+
+The *count_connectors* and *connectors* fields list the available physical
+connectors on the system. Note that some of these may not be exposed
+from the chassis (e.g., LVDS or eDP). Connectors are attached to
+encoders and contain information about the attached display sink (e.g.,
+width and height in mm, subpixel ordering, and various other
+properties).
+
+The *count_encoders* and *encoders* fields list the available encoders on
+the device. Each encoder may be associated with a CRTC, and may be used
+to drive a particular encoder.
+
+The *min_\** and *max_\** fields indicate the maximum size of a framebuffer
+for this device (i.e., the scanout size limit).
+
+Return Value
+============
+
+``drmModeGetResources`` returns a drmModeRes structure pointer on
+success, NULL on failure. The returned structure must be freed with
+**drmModeFreeResources**\ (3).
+
+Reporting Bugs
+==============
+
+Bugs in this function should be reported to
+https://gitlab.freedesktop.org/mesa/drm/-/issues
+
+See Also
+========
+
+**drm**\ (7), **drm-kms**\ (7), **drmModeGetFB**\ (3), **drmModeAddFB**\ (3),
+**drmModeAddFB2**\ (3), **drmModeRmFB**\ (3), **drmModeDirtyFB**\ (3),
+**drmModeGetCrtc**\ (3), **drmModeSetCrtc** (3), **drmModeGetEncoder** (3),
+**drmModeGetConnector**\ (3)
diff --git a/man/drmModeGetResources.xml b/man/drmModeGetResources.xml
deleted file mode 100644
index 0ab6a68b..00000000
--- a/man/drmModeGetResources.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
- Dedicated to the Public Domain
--->
-
-<refentry id="drmModeGetResources">
- <refentryinfo>
- <title>Direct Rendering Manager</title>
- <productname>libdrm</productname>
- <date>September 2012</date>
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>David</firstname>
- <surname>Herrmann</surname>
- <email>dh.herrmann@googlemail.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>drmModeGetResources</refentrytitle>
- <manvolnum>3</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>drmModeGetResources</refname>
- <refpurpose>retrieve current display configuration information</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
-
- <funcsynopsis>
- <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
- <funcsynopsisinfo>#include &lt;xf86drmMode.h&gt;</funcsynopsisinfo>
-
- <funcprototype>
- <funcdef>drmModeResPtr <function>drmModeGetResources</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- </funcprototype>
- </funcsynopsis>
-
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
- <para><function>drmModeGetResources</function> allocates, populates, and
- returns a <structname>drmModeRes</structname> structure containing
- information about the current display configuration. The structure
- contains the following fields:
-
-<programlisting>
-typedef struct _drmModeRes {
- int count_fbs;
- uint32_t *fbs;
-
- int count_crtcs;
- uint32_t *crtcs;
-
- int count_connectors;
- uint32_t *connectors;
-
- int count_encoders;
- uint32_t *encoders;
-
- uint32_t min_width, max_width;
- uint32_t min_height, max_height;
-} drmModeRes, *drmModeResPtr;
-</programlisting>
-
- </para>
-
- <para>The <structfield>count_fbs</structfield> and
- <structfield>fbs</structfield> fields indicate the number of currently
- allocated framebuffer objects (i.e., objects that can be attached to
- a given CRTC or sprite for display).</para>
-
- <para>The <structfield>count_crtcs</structfield> and
- <structfield>crtcs</structfield> fields list the available CRTCs in
- the configuration. A CRTC is simply an object that can scan out a
- framebuffer to a display sink, and contains mode timing and relative
- position information. CRTCs drive encoders, which are responsible for
- converting the pixel stream into a specific display protocol (e.g.,
- MIPI or HDMI).</para>
-
- <para>The <structfield>count_connectors</structfield> and
- <structfield>connectors</structfield> fields list the available
- physical connectors on the system. Note that some of these may not be
- exposed from the chassis (e.g., LVDS or eDP). Connectors are attached
- to encoders and contain information about the attached display sink
- (e.g., width and height in mm, subpixel ordering, and various other
- properties).</para>
-
- <para>The <structfield>count_encoders</structfield> and
- <structfield>encoders</structfield> fields list the available encoders
- on the device. Each encoder may be associated with a CRTC, and may be
- used to drive a particular encoder.</para>
-
- <para>The <structfield>min*</structfield> and
- <structfield>max*</structfield> fields indicate the maximum size of a
- framebuffer for this device (i.e., the scanout size limit).</para>
- </refsect1>
-
- <refsect1>
- <title>Return Value</title>
- <para><function>drmModeGetResources</function> returns a drmModeRes
- structure pointer on success, <literal>NULL</literal> on failure. The
- returned structure must be freed with
- <citerefentry><refentrytitle>drmModeFreeResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
- </refsect1>
-
- <refsect1>
- <title>Reporting Bugs</title>
- <para>Bugs in this function should be reported to
- https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&amp;component=libdrm
- under the "DRI" product, component "libdrm"</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeRmFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeDirtyFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetEncoder</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- </para>
- </refsect1>
-</refentry>
diff --git a/man/meson.build b/man/meson.build
index 45eaeda0..92a4c375 100644
--- a/man/meson.build
+++ b/man/meson.build
@@ -18,50 +18,23 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
-xsltproc_args = [
- '--stringparam', 'man.authors.section.enabled', '0',
- '--stringparam', 'man.copyright.section.enabled', '0',
- '--stringparam', 'funcsynopsis.style', 'ansi',
- '--stringparam', 'man.output.quietly', '1',
- '--nonet', manpage_style,
+rst_pages = [
+ ['drm', '7'],
+ ['drm-kms', '7'],
+ ['drm-memory', '7'],
+ ['drmAvailable', '3'],
+ ['drmHandleEvent', '3'],
+ ['drmModeGetResources', '3'],
]
-
-xmls = [
- ['drm', '7'], ['drm-kms', '7'], ['drm-memory', '7'], ['drmAvailable', '3'],
- ['drmHandleEvent', '3'], ['drmModeGetResources', '3']
-]
-foreach x : xmls
- m = x[0]
- s = x[1]
- custom_target(
- m,
- input : files('@0@.xml'.format(m)),
- output : '@0@.@1@'.format(m, s),
- command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT0@'],
- install : true,
- install_dir : join_paths(get_option('mandir'), 'man@0@'.format(s)),
- build_by_default : true,
- )
-endforeach
-
-foreach x : ['drm-mm', 'drm-gem', 'drm-ttm']
- gen = custom_target(
- 'gen-@0@'.format(x),
- input : 'drm-memory.xml',
- output : '@0@.xml'.format(x),
- command : [
- prog_sed, '-e', 's@^\.so \([a-z_]\+\)\.\([0-9]\)$$@\.so man\2\/\1\.\2@',
- '@INPUT@',
- ],
- capture : true,
- )
+foreach page : rst_pages
+ name = page[0] + '.' + page[1]
+ rst = files(name + '.rst')
custom_target(
- '@0@.7'.format(x),
- input : gen,
- output : '@0@.7'.format(x, '7'),
- command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT@'],
+ name,
+ input : rst,
+ output : name,
+ command : [prog_rst2man, '@INPUT@', '@OUTPUT@'],
install : true,
- install_dir : join_paths(get_option('mandir'), 'man7'),
- build_by_default : true,
+ install_dir : join_paths(get_option('mandir'), 'man' + page[1]),
)
endforeach
diff --git a/meson.build b/meson.build
index e292554a..07d2e086 100644
--- a/meson.build
+++ b/meson.build
@@ -21,7 +21,7 @@
project(
'libdrm',
['c'],
- version : '2.4.99',
+ version : '2.4.104',
license : 'MIT',
meson_version : '>= 0.43',
default_options : ['buildtype=debugoptimized', 'c_std=gnu99'],
@@ -44,14 +44,18 @@ dep_threads = dependency('threads')
cc = meson.get_compiler('c')
+symbols_check = find_program('symbols-check.py')
+prog_nm = find_program('nm')
+
# Check for atomics
intel_atomics = false
lib_atomics = false
dep_atomic_ops = dependency('atomic_ops', required : false)
-if cc.compiles('''
+if cc.links('''
int atomic_add(int *i) { return __sync_add_and_fetch (i, 1); }
int atomic_cmpxchg(int *i, int j, int k) { return __sync_val_compare_and_swap (i, j, k); }
+ int main() { }
''',
name : 'Intel Atomics')
intel_atomics = true
@@ -179,13 +183,31 @@ else
dep_rt = []
endif
dep_m = cc.find_library('m', required : false)
-foreach header : ['sys/sysctl.h', 'sys/select.h', 'alloca.h']
- config.set('HAVE_' + header.underscorify().to_upper(),
+
+# The header is not required on Linux, and is in fact deprecated in glibc 2.30+
+if ['linux'].contains(host_machine.system())
+ config.set10('HAVE_SYS_SYSCTL_H', false)
+else
+ # From Niclas Zeising:
+ # FreeBSD requires sys/types.h for sys/sysctl.h, so add it as part of
+ # the includes when checking for headers.
+ config.set10('HAVE_SYS_SYSCTL_H',
+ cc.compiles('#include <sys/types.h>\n#include <sys/sysctl.h>', name : 'sys/sysctl.h works'))
+endif
+
+foreach header : ['sys/select.h', 'alloca.h']
+ config.set10('HAVE_' + header.underscorify().to_upper(),
cc.compiles('#include <@0@>'.format(header), name : '@0@ works'.format(header)))
endforeach
-if cc.has_header_symbol('sys/sysmacros.h', 'major')
+
+if (cc.has_header_symbol('sys/sysmacros.h', 'major') and
+ cc.has_header_symbol('sys/sysmacros.h', 'minor') and
+ cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
config.set10('MAJOR_IN_SYSMACROS', true)
-elif cc.has_header_symbol('sys/mkdev.h', 'major')
+endif
+if (cc.has_header_symbol('sys/mkdev.h', 'major') and
+ cc.has_header_symbol('sys/mkdev.h', 'minor') and
+ cc.has_header_symbol('sys/mkdev.h', 'makedev'))
config.set10('MAJOR_IN_MKDEV', true)
endif
config.set10('HAVE_OPEN_MEMSTREAM', cc.has_function('open_memstream'))
@@ -227,7 +249,11 @@ else
endif
_valgrind = get_option('valgrind')
if _valgrind != 'false'
- dep_valgrind = dependency('valgrind', required : _valgrind == 'true')
+ if with_freedreno
+ dep_valgrind = dependency('valgrind', required : _valgrind == 'true', version : '>=3.10.0')
+ else
+ dep_valgrind = dependency('valgrind', required : _valgrind == 'true')
+ endif
with_valgrind = dep_valgrind.found()
else
dep_valgrind = []
@@ -235,21 +261,8 @@ else
endif
with_man_pages = get_option('man-pages')
-prog_xslt = find_program('xsltproc', required : with_man_pages == 'true')
-prog_sed = find_program('sed', required : with_man_pages == 'true')
-manpage_style = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
-if prog_xslt.found()
- if run_command(prog_xslt, '--nonet', manpage_style).returncode() != 0
- if with_man_pages == 'true'
- error('Manpage style sheet cannot be found')
- endif
- with_man_pages = 'false'
- endif
-endif
-with_man_pages = with_man_pages != 'false' and prog_xslt.found() and prog_sed.found()
-
-# Used for tets
-prog_bash = find_program('bash')
+prog_rst2man = find_program('rst2man', 'rst2man.py', required: with_man_pages == 'true')
+with_man_pages = with_man_pages != 'false' and prog_rst2man.found()
config.set10('HAVE_VISIBILITY',
cc.compiles('''int foo_hidden(void) __attribute__((visibility(("hidden"))));''',
@@ -276,7 +289,7 @@ config_file = configure_file(
configuration : config,
output : 'config.h',
)
-add_project_arguments('-include', 'config.h', language : 'c')
+add_project_arguments('-include', '@0@'.format(config_file), language : 'c')
inc_root = include_directories('.')
inc_drm = include_directories('include/drm')
@@ -296,6 +309,16 @@ libdrm = shared_library(
install : true,
)
+test(
+ 'core-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm,
+ '--symbols-file', files('core-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
+)
+
ext_libdrm = declare_dependency(
link_with : libdrm,
include_directories : [inc_root, inc_drm],
@@ -326,9 +349,6 @@ pkg.generate(
description : 'Userspace interface to kernel DRM services',
)
-env_test = environment()
-env_test.set('NM', find_program('nm').path())
-
if with_libkms
subdir('libkms')
endif
diff --git a/nouveau/Android.bp b/nouveau/Android.bp
index 12c37e3d..b844fdde 100644
--- a/nouveau/Android.bp
+++ b/nouveau/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_shared {
diff --git a/nouveau/Makefile.am b/nouveau/Makefile.am
deleted file mode 100644
index 5574fd8f..00000000
--- a/nouveau/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-include Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm \
- -DDEBUG
-
-libdrm_nouveau_la_LTLIBRARIES = libdrm_nouveau.la
-libdrm_nouveau_ladir = $(libdir)
-libdrm_nouveau_la_LDFLAGS = -version-number 2:0:0 -no-undefined
-libdrm_nouveau_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
-
-libdrm_nouveau_la_SOURCES = $(LIBDRM_NOUVEAU_FILES)
-
-libdrm_nouveauincludedir = ${includedir}/libdrm/nouveau
-libdrm_nouveauinclude_HEADERS = $(LIBDRM_NOUVEAU_H_FILES)
-
-libdrm_nouveaunvifincludedir = ${includedir}/libdrm/nouveau/nvif
-libdrm_nouveaunvifinclude_HEADERS = nvif/class.h \
- nvif/cl0080.h \
- nvif/cl9097.h \
- nvif/if0002.h \
- nvif/if0003.h \
- nvif/ioctl.h \
- nvif/unpack.h
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_nouveau.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = nouveau-symbol-check
-EXTRA_DIST = $(TESTS)
diff --git a/nouveau/meson.build b/nouveau/meson.build
index 0c1498d7..9bd58fca 100644
--- a/nouveau/meson.build
+++ b/nouveau/meson.build
@@ -52,8 +52,11 @@ pkg.generate(
)
test(
- 'nouveau-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('nouveau-symbol-check'), libdrm_nouveau]
+ 'nouveau-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_nouveau,
+ '--symbols-file', files('nouveau-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbols.txt
index 6296244c..ef8032f2 100755..100644
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbols.txt
@@ -1,17 +1,3 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.sources/LIBDRM_NOUVEAU_H_FILES
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_nouveau.so} | awk '{print $3}'| while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
nouveau_bo_map
nouveau_bo_name_get
nouveau_bo_name_ref
@@ -53,8 +39,3 @@ nouveau_pushbuf_reloc
nouveau_pushbuf_space
nouveau_pushbuf_validate
nouveau_setparam
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/nouveau/private.h b/nouveau/private.h
index 83060f96..034a958e 100644
--- a/nouveau/private.h
+++ b/nouveau/private.h
@@ -10,7 +10,7 @@
#include "nouveau.h"
#ifdef DEBUG
-drm_private uint32_t nouveau_debug;
+drm_private extern uint32_t nouveau_debug;
#define dbg_on(lvl) (nouveau_debug & (1 << lvl))
#define dbg(lvl, fmt, args...) do { \
if (dbg_on((lvl))) \
diff --git a/omap/Android.bp b/omap/Android.bp
index 05ca7d2d..a3a5a9e3 100644
--- a/omap/Android.bp
+++ b/omap/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_shared {
diff --git a/omap/Makefile.am b/omap/Makefile.am
deleted file mode 100644
index 38a1007b..00000000
--- a/omap/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_omap_la_LTLIBRARIES = libdrm_omap.la
-libdrm_omap_ladir = $(libdir)
-libdrm_omap_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libdrm_omap_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
-
-libdrm_omap_la_SOURCES = omap_drm.c
-
-libdrm_omapcommonincludedir = ${includedir}/omap
-libdrm_omapcommoninclude_HEADERS = omap_drm.h
-
-libdrm_omapincludedir = ${includedir}/libdrm
-libdrm_omapinclude_HEADERS = omap_drmif.h
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_omap.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = omap-symbol-check
-EXTRA_DIST = $(TESTS)
diff --git a/omap/meson.build b/omap/meson.build
index 54698c6a..53330b61 100644
--- a/omap/meson.build
+++ b/omap/meson.build
@@ -47,8 +47,11 @@ pkg.generate(
)
test(
- 'omap-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('omap-symbol-check'), libdrm_omap]
+ 'omap-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_omap,
+ '--symbols-file', files('omap-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/omap/omap-symbol-check b/omap/omap-symbol-check
deleted file mode 100755
index 16da3c40..00000000
--- a/omap/omap-symbol-check
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.am/libdrm_omap*HEADERS
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_omap.so} | awk '{print $3}'| while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
-omap_bo_cpu_fini
-omap_bo_cpu_prep
-omap_bo_del
-omap_bo_dmabuf
-omap_bo_from_dmabuf
-omap_bo_from_name
-omap_bo_get_name
-omap_bo_handle
-omap_bo_map
-omap_bo_new
-omap_bo_new_tiled
-omap_bo_ref
-omap_bo_size
-omap_device_del
-omap_device_new
-omap_device_ref
-omap_get_param
-omap_set_param
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/omap/omap-symbols.txt b/omap/omap-symbols.txt
new file mode 100644
index 00000000..749d0f7c
--- /dev/null
+++ b/omap/omap-symbols.txt
@@ -0,0 +1,18 @@
+omap_bo_cpu_fini
+omap_bo_cpu_prep
+omap_bo_del
+omap_bo_dmabuf
+omap_bo_from_dmabuf
+omap_bo_from_name
+omap_bo_get_name
+omap_bo_handle
+omap_bo_map
+omap_bo_new
+omap_bo_new_tiled
+omap_bo_ref
+omap_bo_size
+omap_device_del
+omap_device_new
+omap_device_ref
+omap_get_param
+omap_set_param
diff --git a/radeon/Android.bp b/radeon/Android.bp
index 9d0a09ec..6c52084f 100644
--- a/radeon/Android.bp
+++ b/radeon/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_shared {
diff --git a/radeon/Makefile.am b/radeon/Makefile.am
deleted file mode 100644
index e712a4ac..00000000
--- a/radeon/Makefile.am
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright © 2008 Jérôme Glisse
-#
-# 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 AUTHORS OR COPYRIGHT HOLDERS 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.
-#
-# Authors:
-# Jérôme Glisse <glisse@freedesktop.org>
-
-include Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_radeon_la_LTLIBRARIES = libdrm_radeon.la
-libdrm_radeon_ladir = $(libdir)
-libdrm_radeon_la_LDFLAGS = -version-number 1:0:1 -no-undefined
-libdrm_radeon_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
-
-libdrm_radeon_la_SOURCES = $(LIBDRM_RADEON_FILES)
-
-libdrm_radeonincludedir = ${includedir}/libdrm
-libdrm_radeoninclude_HEADERS = $(LIBDRM_RADEON_H_FILES)
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_radeon.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = radeon-symbol-check
-EXTRA_DIST = $(LIBDRM_RADEON_BOF_FILES) $(TESTS)
diff --git a/radeon/meson.build b/radeon/meson.build
index 1fc5282c..ca128329 100644
--- a/radeon/meson.build
+++ b/radeon/meson.build
@@ -57,8 +57,11 @@ pkg.generate(
)
test(
- 'radeon-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('radeon-symbol-check'), libdrm_radeon]
+ 'radeon-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_radeon,
+ '--symbols-file', files('radeon-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/radeon/radeon-symbol-check b/radeon/radeon-symbols.txt
index da605bb8..5a532d83 100755..100644
--- a/radeon/radeon-symbol-check
+++ b/radeon/radeon-symbols.txt
@@ -1,17 +1,3 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first five) are taken from the public headers.
-# A list of the latter should be available Makefile.sources/LIBDRM_RADEON_H_FILES
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_radeon.so} | awk '{print $3}'| while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_start
-_edata
-_end
-_fini
-_init
radeon_bo_debug
radeon_bo_get_handle
radeon_bo_get_src_domain
@@ -56,8 +42,3 @@ radeon_surface_best
radeon_surface_init
radeon_surface_manager_free
radeon_surface_manager_new
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/symbols-check.py b/symbols-check.py
new file mode 100644
index 00000000..2e7ba68d
--- /dev/null
+++ b/symbols-check.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import platform
+import subprocess
+
+# This list contains symbols that _might_ be exported for some platforms
+PLATFORM_SYMBOLS = [
+ '__bss_end__',
+ '__bss_start__',
+ '__bss_start',
+ '__end__',
+ '_bss_end__',
+ '_edata',
+ '_end',
+ '_fini',
+ '_init',
+]
+
+
+def get_symbols(nm, lib):
+ '''
+ List all the (non platform-specific) symbols exported by the library
+ '''
+ symbols = []
+ platform_name = platform.system()
+ output = subprocess.check_output([nm, '-gP', lib],
+ stderr=open(os.devnull, 'w')).decode("ascii")
+ for line in output.splitlines():
+ fields = line.split()
+ if len(fields) == 2 or fields[1] == 'U':
+ continue
+ symbol_name = fields[0]
+ if platform_name == 'Linux':
+ if symbol_name in PLATFORM_SYMBOLS:
+ continue
+ elif platform_name == 'Darwin':
+ assert symbol_name[0] == '_'
+ symbol_name = symbol_name[1:]
+ symbols.append(symbol_name)
+
+ return symbols
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--symbols-file',
+ action='store',
+ required=True,
+ help='path to file containing symbols')
+ parser.add_argument('--lib',
+ action='store',
+ required=True,
+ help='path to library')
+ parser.add_argument('--nm',
+ action='store',
+ required=True,
+ help='path to binary (or name in $PATH)')
+ args = parser.parse_args()
+
+ try:
+ lib_symbols = get_symbols(args.nm, args.lib)
+ except:
+ # We can't run this test, but we haven't technically failed it either
+ # Return the GNU "skip" error code
+ exit(77)
+ mandatory_symbols = []
+ optional_symbols = []
+ with open(args.symbols_file) as symbols_file:
+ qualifier_optional = '(optional)'
+ for line in symbols_file.readlines():
+
+ # Strip comments
+ line = line.split('#')[0]
+ line = line.strip()
+ if not line:
+ continue
+
+ # Line format:
+ # [qualifier] symbol
+ qualifier = None
+ symbol = None
+
+ fields = line.split()
+ if len(fields) == 1:
+ symbol = fields[0]
+ elif len(fields) == 2:
+ qualifier = fields[0]
+ symbol = fields[1]
+ else:
+ print(args.symbols_file + ': invalid format: ' + line)
+ exit(1)
+
+ # The only supported qualifier is 'optional', which means the
+ # symbol doesn't have to be exported by the library
+ if qualifier and not qualifier == qualifier_optional:
+ print(args.symbols_file + ': invalid qualifier: ' + qualifier)
+ exit(1)
+
+ if qualifier == qualifier_optional:
+ optional_symbols.append(symbol)
+ else:
+ mandatory_symbols.append(symbol)
+
+ unknown_symbols = []
+ for symbol in lib_symbols:
+ if symbol in mandatory_symbols:
+ continue
+ if symbol in optional_symbols:
+ continue
+ unknown_symbols.append(symbol)
+
+ missing_symbols = [
+ sym for sym in mandatory_symbols if sym not in lib_symbols
+ ]
+
+ for symbol in unknown_symbols:
+ print(args.lib + ': unknown symbol exported: ' + symbol)
+
+ for symbol in missing_symbols:
+ print(args.lib + ': missing symbol: ' + symbol)
+
+ if unknown_symbols or missing_symbols:
+ exit(1)
+ exit(0)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tegra/Android.bp b/tegra/Android.bp
index 33eaf6c5..297c0193 100644
--- a/tegra/Android.bp
+++ b/tegra/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
cc_library_shared {
name: "libdrm_tegra",
vendor: true,
diff --git a/tegra/Makefile.am b/tegra/Makefile.am
deleted file mode 100644
index 53119970..00000000
--- a/tegra/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include/drm
-
-AM_CFLAGS = \
- @PTHREADSTUBS_CFLAGS@ \
- $(WARN_CFLAGS) \
- -fvisibility=hidden
-
-libdrm_tegra_ladir = $(libdir)
-libdrm_tegra_la_LTLIBRARIES = libdrm_tegra.la
-libdrm_tegra_la_LDFLAGS = -version-number 0:0:0 -no-undefined
-libdrm_tegra_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
-
-libdrm_tegra_la_SOURCES = \
- private.h \
- tegra.c
-
-libdrm_tegraincludedir = ${includedir}/libdrm
-libdrm_tegrainclude_HEADERS = tegra.h
-
-pkgconfigdir = @pkgconfigdir@
-pkgconfig_DATA = libdrm_tegra.pc
-
-AM_TESTS_ENVIRONMENT = NM='$(NM)'
-TESTS = tegra-symbol-check
-EXTRA_DIST = $(TESTS)
diff --git a/tegra/meson.build b/tegra/meson.build
index 4bc454b6..88613b9c 100644
--- a/tegra/meson.build
+++ b/tegra/meson.build
@@ -46,8 +46,11 @@ pkg.generate(
)
test(
- 'tegra-symbol-check',
- prog_bash,
- env : env_test,
- args : [files('tegra-symbol-check'), libdrm_tegra]
+ 'tegra-symbols-check',
+ symbols_check,
+ args : [
+ '--lib', libdrm_tegra,
+ '--symbols-file', files('tegra-symbols.txt'),
+ '--nm', prog_nm.path(),
+ ],
)
diff --git a/tegra/tegra-symbol-check b/tegra/tegra-symbol-check
deleted file mode 100755
index 8539b95b..00000000
--- a/tegra/tegra-symbol-check
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-set -u
-
-# The following symbols (past the first nine) are taken from tegra.h.
-
-FUNCS=$($NM -D --format=bsd --defined-only ${1-.libs/libdrm_tegra.so} | awk '{print $3}'| while read func; do
-( grep -q "^$func$" || echo $func ) <<EOF
-__bss_end__
-__bss_start__
-__bss_start
-__end__
-_bss_end__
-_edata
-_end
-_fini
-_init
-drm_tegra_bo_get_flags
-drm_tegra_bo_get_handle
-drm_tegra_bo_get_tiling
-drm_tegra_bo_map
-drm_tegra_bo_new
-drm_tegra_bo_ref
-drm_tegra_bo_set_flags
-drm_tegra_bo_set_tiling
-drm_tegra_bo_unmap
-drm_tegra_bo_unref
-drm_tegra_bo_wrap
-drm_tegra_close
-drm_tegra_new
-EOF
-done)
-
-test ! -n "$FUNCS" || echo $FUNCS
-test ! -n "$FUNCS"
diff --git a/tegra/tegra-symbols.txt b/tegra/tegra-symbols.txt
new file mode 100644
index 00000000..5e3e955f
--- /dev/null
+++ b/tegra/tegra-symbols.txt
@@ -0,0 +1,13 @@
+drm_tegra_bo_get_flags
+drm_tegra_bo_get_handle
+drm_tegra_bo_get_tiling
+drm_tegra_bo_map
+drm_tegra_bo_new
+drm_tegra_bo_ref
+drm_tegra_bo_set_flags
+drm_tegra_bo_set_tiling
+drm_tegra_bo_unmap
+drm_tegra_bo_unref
+drm_tegra_bo_wrap
+drm_tegra_close
+drm_tegra_new
diff --git a/tests/Android.bp b/tests/Android.bp
index cdc6c2cf..bff7f991 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
subdirs = ["*"]
cc_library_headers {
diff --git a/tests/Makefile.am b/tests/Makefile.am
deleted file mode 100644
index d274a3e9..00000000
--- a/tests/Makefile.am
+++ /dev/null
@@ -1,53 +0,0 @@
-SUBDIRS = util kms modeprint proptest modetest vbltest
-
-if HAVE_LIBKMS
-SUBDIRS += kmstest
-endif
-
-if HAVE_RADEON
-SUBDIRS += radeon
-endif
-
-if HAVE_AMDGPU
-if HAVE_CUNIT
-SUBDIRS += amdgpu
-endif
-endif
-
-if HAVE_EXYNOS
-SUBDIRS += exynos
-endif
-
-if HAVE_TEGRA
-SUBDIRS += tegra
-endif
-
-if HAVE_ETNAVIV
-SUBDIRS += etnaviv
-endif
-
-if HAVE_NOUVEAU
-SUBDIRS += nouveau
-endif
-
-AM_CFLAGS = \
- $(WARN_CFLAGS)\
- -fvisibility=hidden \
- -I $(top_srcdir)/include/drm \
- -I $(top_srcdir)
-
-LDADD = $(top_builddir)/libdrm.la
-
-TESTS = \
- drmsl \
- hash \
- random
-
-check_PROGRAMS = \
- $(TESTS)
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = drmdevice
-else
-check_PROGRAMS += drmdevice
-endif
diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
deleted file mode 100644
index 920882d0..00000000
--- a/tests/amdgpu/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-AM_CFLAGS = \
- -fvisibility=hidden \
- -I $(top_srcdir)/include/drm \
- -I $(top_srcdir)/amdgpu \
- -I $(top_srcdir) \
- -pthread
-
-LDADD = $(top_builddir)/libdrm.la \
- $(top_builddir)/amdgpu/libdrm_amdgpu.la \
- $(CUNIT_LIBS)
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- amdgpu_test
-else
-noinst_PROGRAMS = \
- amdgpu_test
-endif
-
-amdgpu_test_CPPFLAGS = $(CUNIT_CFLAGS)
-
-amdgpu_test_SOURCES = \
- amdgpu_test.c \
- amdgpu_test.h \
- basic_tests.c \
- bo_tests.c \
- cs_tests.c \
- decode_messages.h \
- vce_tests.c \
- vce_ib.h \
- frame.h \
- uvd_enc_tests.c \
- vcn_tests.c \
- uve_ib.h \
- deadlock_tests.c \
- vm_tests.c \
- ras_tests.c \
- syncobj_tests.c
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index 73403fb4..8c867678 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/tests/amdgpu/amdgpu_test.c
@@ -58,6 +58,7 @@
#define VM_TESTS_STR "VM Tests"
#define RAS_TESTS_STR "RAS Tests"
#define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests"
+#define SECURITY_TESTS_STR "Security Tests"
/**
* Open handles for amdgpu devices
@@ -130,6 +131,12 @@ static CU_SuiteInfo suites[] = {
.pCleanupFunc = suite_syncobj_timeline_tests_clean,
.pTests = syncobj_timeline_tests,
},
+ {
+ .pName = SECURITY_TESTS_STR,
+ .pInitFunc = suite_security_tests_init,
+ .pCleanupFunc = suite_security_tests_clean,
+ .pTests = security_tests,
+ },
CU_SUITE_INFO_NULL,
};
@@ -149,7 +156,7 @@ static CU_BOOL always_active()
static Suites_Active_Status suites_active_stat[] = {
{
.pName = BASIC_TESTS_STR,
- .pActive = always_active,
+ .pActive = suite_basic_tests_enable,
},
{
.pName = BO_TESTS_STR,
@@ -187,6 +194,10 @@ static Suites_Active_Status suites_active_stat[] = {
.pName = SYNCOBJ_TIMELINE_TESTS_STR,
.pActive = suite_syncobj_timeline_tests_enable,
},
+ {
+ .pName = SECURITY_TESTS_STR,
+ .pActive = suite_security_tests_enable,
+ },
};
@@ -202,44 +213,42 @@ static void display_test_suites(void)
CU_pSuite pSuite = NULL;
CU_pTest pTest = NULL;
- printf("Suites\n");
+ printf("%5s: %2s: %8s: %s\n", "What", "ID", "Status", "Name");
for (iSuite = 0; suites[iSuite].pName != NULL; iSuite++) {
pSuite = CU_get_suite_by_index((unsigned int) iSuite + 1,
- CU_get_registry());
+ CU_get_registry());
if (!pSuite) {
fprintf(stderr, "Invalid suite id : %d\n", iSuite + 1);
continue;
}
- printf("Suite id = %d: Name '%s status: %s'\n",
- iSuite + 1, suites[iSuite].pName,
- pSuite->fActive ? "ENABLED" : "DISABLED");
-
+ printf("Suite: %2d: %8s: %s\n",
+ iSuite + 1,
+ pSuite->fActive ? "ENABLED" : "DISABLED",
+ suites[iSuite].pName);
+ if (!pSuite->fActive)
+ continue;
for (iTest = 0; suites[iSuite].pTests[iTest].pName != NULL;
- iTest++) {
-
+ iTest++) {
pTest = CU_get_test_by_index((unsigned int) iTest + 1,
- pSuite);
-
+ pSuite);
if (!pTest) {
fprintf(stderr, "Invalid test id : %d\n", iTest + 1);
continue;
}
-
- printf("Test id %d: Name: '%s status: %s'\n", iTest + 1,
- suites[iSuite].pTests[iTest].pName,
- pSuite->fActive && pTest->fActive ?
- "ENABLED" : "DISABLED");
+ printf(" Test: %2d: %8s: %s\n",
+ iTest + 1,
+ pSuite->fActive && pTest->fActive ? "ENABLED" : "DISABLED",
+ suites[iSuite].pTests[iTest].pName);
}
}
}
-
/** Help string for command line parameters */
static const char usage[] =
"Usage: %s [-hlpr] [<-s <suite id>> [-t <test id>] [-f]] "
@@ -452,6 +461,41 @@ static void amdgpu_disable_suites()
"sdma ring block test (set amdgpu.lockup_timeout=50)", CU_FALSE))
fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "gfx ring bad dispatch test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "compute ring bad dispatch test (set amdgpu.lockup_timeout=50,50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "gfx ring bad slow dispatch test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(DEADLOCK_TESTS_STR,
+ "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
if (amdgpu_set_test_active(BO_TESTS_STR, "Metadata", CU_FALSE))
fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
@@ -464,14 +508,22 @@ static void amdgpu_disable_suites()
fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
/* This test was ran on GFX9 only */
- if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
- if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test", CU_FALSE))
+ if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV) {
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test (GFX)", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "Dispatch Test (Compute)", CU_FALSE))
fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+ }
/* This test was ran on GFX9 only */
if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
if (amdgpu_set_test_active(BASIC_TESTS_STR, "Draw Test", CU_FALSE))
fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
+
+ /* This test was ran on GFX9 only */
+ //if (family_id < AMDGPU_FAMILY_AI || family_id > AMDGPU_FAMILY_RV)
+ if (amdgpu_set_test_active(BASIC_TESTS_STR, "GPU reset Test", CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg());
}
/* The main() function for setting up and running the tests.
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
index 36675ea3..98cec698 100644
--- a/tests/amdgpu/amdgpu_test.h
+++ b/tests/amdgpu/amdgpu_test.h
@@ -55,6 +55,11 @@ int suite_basic_tests_init();
int suite_basic_tests_clean();
/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_basic_tests_enable(void);
+
+/**
* Tests in basic test suite
*/
extern CU_TestInfo basic_tests[];
@@ -236,6 +241,37 @@ CU_BOOL suite_syncobj_timeline_tests_enable(void);
*/
extern CU_TestInfo syncobj_timeline_tests[];
+void amdgpu_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip_type);
+void amdgpu_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip_type);
+void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t ring,
+ int hang);
+void amdgpu_memcpy_draw_hang_slow_test(amdgpu_device_handle device_handle, uint32_t ring);
+
+/**
+ * Initialize security test suite
+ */
+int suite_security_tests_init();
+
+/**
+ * Deinitialize security test suite
+ */
+int suite_security_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_security_tests_enable(void);
+
+/**
+ * Tests in security test suite
+ */
+extern CU_TestInfo security_tests[];
+
+extern void
+amdgpu_command_submission_write_linear_helper_with_secure(amdgpu_device_handle
+ device,
+ unsigned ip_type,
+ bool secure);
/**
* Helper functions
@@ -413,4 +449,26 @@ static inline CU_ErrorCode amdgpu_set_test_active(const char *suite_name,
return r;
}
+static inline bool asic_is_arcturus(uint32_t asic_id)
+{
+ switch(asic_id) {
+ /* Arcturus asic DID */
+ case 0x738C:
+ case 0x7388:
+ case 0x738E:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void amdgpu_test_exec_cs_helper_raw(amdgpu_device_handle device_handle,
+ amdgpu_context_handle context_handle,
+ unsigned ip_type, int instance, int pm4_dw,
+ uint32_t *pm4_src, int res_cnt,
+ amdgpu_bo_handle *resources,
+ struct amdgpu_cs_ib_info *ib_info,
+ struct amdgpu_cs_request *ibs_request,
+ bool secure);
+
#endif /* #ifdef _AMDGPU_TEST_H_ */
diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c
index 2d472691..dc9ed947 100644
--- a/tests/amdgpu/basic_tests.c
+++ b/tests/amdgpu/basic_tests.c
@@ -24,7 +24,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#ifdef HAVE_ALLOCA_H
+#include <sys/types.h>
+#ifdef MAJOR_IN_SYSMACROS
+#include <sys/sysmacros.h>
+#endif
+#include <sys/stat.h>
+#include <fcntl.h>
+#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include <sys/wait.h>
@@ -33,6 +39,7 @@
#include "amdgpu_test.h"
#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
#include "util_math.h"
static amdgpu_device_handle device_handle;
@@ -49,8 +56,10 @@ static void amdgpu_userptr_test(void);
static void amdgpu_semaphore_test(void);
static void amdgpu_sync_dependency_test(void);
static void amdgpu_bo_eviction_test(void);
-static void amdgpu_dispatch_test(void);
+static void amdgpu_compute_dispatch_test(void);
+static void amdgpu_gfx_dispatch_test(void);
static void amdgpu_draw_test(void);
+static void amdgpu_gpu_reset_test(void);
static void amdgpu_command_submission_write_linear_helper(unsigned ip_type);
static void amdgpu_command_submission_const_fill_helper(unsigned ip_type);
@@ -61,7 +70,7 @@ static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
int res_cnt, amdgpu_bo_handle *resources,
struct amdgpu_cs_ib_info *ib_info,
struct amdgpu_cs_request *ibs_request);
-
+
CU_TestInfo basic_tests[] = {
{ "Query Info Test", amdgpu_query_info_test },
{ "Userptr Test", amdgpu_userptr_test },
@@ -72,11 +81,13 @@ CU_TestInfo basic_tests[] = {
{ "Command submission Test (SDMA)", amdgpu_command_submission_sdma },
{ "SW semaphore Test", amdgpu_semaphore_test },
{ "Sync dependency Test", amdgpu_sync_dependency_test },
- { "Dispatch Test", amdgpu_dispatch_test },
+ { "Dispatch Test (Compute)", amdgpu_compute_dispatch_test },
+ { "Dispatch Test (GFX)", amdgpu_gfx_dispatch_test },
{ "Draw Test", amdgpu_draw_test },
+ { "GPU reset Test", amdgpu_gpu_reset_test },
CU_TEST_INFO_NULL,
};
-#define BUFFER_SIZE (8 * 1024)
+#define BUFFER_SIZE (MAX2(8 * 1024, getpagesize()))
#define SDMA_PKT_HEADER_op_offset 0
#define SDMA_PKT_HEADER_op_mask 0x000000FF
#define SDMA_PKT_HEADER_op_shift 0
@@ -96,6 +107,20 @@ CU_TestInfo basic_tests[] = {
#define SDMA_OPCODE_COPY 1
# define SDMA_COPY_SUB_OPCODE_LINEAR 0
+#define SDMA_OPCODE_ATOMIC 10
+# define SDMA_ATOMIC_LOOP(x) ((x) << 0)
+ /* 0 - single_pass_atomic.
+ * 1 - loop_until_compare_satisfied.
+ */
+# define SDMA_ATOMIC_TMZ(x) ((x) << 2)
+ /* 0 - non-TMZ.
+ * 1 - TMZ.
+ */
+# define SDMA_ATOMIC_OPCODE(x) ((x) << 9)
+ /* TC_OP_ATOMIC_CMPSWAP_RTN_32 0x00000008
+ * same as Packet 3
+ */
+
#define GFX_COMPUTE_NOP 0xffff1000
#define SDMA_NOP 0x0
@@ -147,6 +172,20 @@ CU_TestInfo basic_tests[] = {
* 2 - ce
*/
+#define PACKET3_ATOMIC_MEM 0x1E
+#define TC_OP_ATOMIC_CMPSWAP_RTN_32 0x00000008
+#define ATOMIC_MEM_COMMAND(x) ((x) << 8)
+ /* 0 - single_pass_atomic.
+ * 1 - loop_until_compare_satisfied.
+ */
+#define ATOMIC_MEM_CACHEPOLICAY(x) ((x) << 25)
+ /* 0 - lru.
+ * 1 - stream.
+ */
+#define ATOMIC_MEM_ENGINESEL(x) ((x) << 30)
+ /* 0 - micro_engine.
+ */
+
#define PACKET3_DMA_DATA 0x50
/* 1. header
* 2. CONTROL
@@ -296,7 +335,9 @@ static uint32_t shader_bin[] = {
enum cs_type {
CS_BUFFERCLEAR,
- CS_BUFFERCOPY
+ CS_BUFFERCOPY,
+ CS_HANG,
+ CS_HANG_SLOW
};
static const uint32_t bufferclear_cs_shader_gfx9[] = {
@@ -329,14 +370,15 @@ static const uint32_t preamblecache_gfx9[] = {
0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0,
0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0,
0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
- 0xc0026900, 0x311, 0x3, 0x0, 0xc0026900, 0x316, 0x1e, 0x20,
+ 0xc0036900, 0x311, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0x1e, 0x20,
0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0,
0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x19, 0x0,
0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0,
0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0,
0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff,
- 0xc0016900, 0x314, 0x0, 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1,
+ 0xc0016900, 0x314, 0x0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0,
+ 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1,
0xc0016900, 0x18, 0x2, 0xc0016900, 0x206, 0x300, 0xc0017900, 0x20000243, 0x0,
0xc0017900, 0x248, 0xffffffff, 0xc0017900, 0x249, 0x0, 0xc0017900, 0x24a, 0x0,
0xc0017900, 0x24b, 0x0
@@ -344,7 +386,9 @@ static const uint32_t preamblecache_gfx9[] = {
enum ps_type {
PS_CONST,
- PS_TEX
+ PS_TEX,
+ PS_HANG,
+ PS_HANG_SLOW
};
static const uint32_t ps_const_shader_gfx9[] = {
@@ -457,6 +501,60 @@ static const uint32_t cached_cmd_gfx9[] = {
0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0
};
+unsigned int memcpy_ps_hang[] = {
+ 0xFFFFFFFF, 0xBEFE0A7E, 0xBEFC0304, 0xC0C20100,
+ 0xC0800300, 0xC8080000, 0xC80C0100, 0xC8090001,
+ 0xC80D0101, 0xBF8C007F, 0xF0800F00, 0x00010002,
+ 0xBEFE040C, 0xBF8C0F70, 0xBF800000, 0xBF800000,
+ 0xF800180F, 0x03020100, 0xBF810000
+};
+
+struct amdgpu_test_shader {
+ uint32_t *shader;
+ uint32_t header_length;
+ uint32_t body_length;
+ uint32_t foot_length;
+};
+
+unsigned int memcpy_cs_hang_slow_ai_codes[] = {
+ 0xd1fd0000, 0x04010c08, 0xe00c2000, 0x80000100,
+ 0xbf8c0f70, 0xe01c2000, 0x80010100, 0xbf810000
+};
+
+struct amdgpu_test_shader memcpy_cs_hang_slow_ai = {
+ memcpy_cs_hang_slow_ai_codes,
+ 4,
+ 3,
+ 1
+};
+
+unsigned int memcpy_cs_hang_slow_rv_codes[] = {
+ 0x8e00860c, 0x32000000, 0xe00c2000, 0x80010100,
+ 0xbf8c0f70, 0xe01c2000, 0x80020100, 0xbf810000
+};
+
+struct amdgpu_test_shader memcpy_cs_hang_slow_rv = {
+ memcpy_cs_hang_slow_rv_codes,
+ 4,
+ 3,
+ 1
+};
+
+unsigned int memcpy_ps_hang_slow_ai_codes[] = {
+ 0xbefc000c, 0xbe8e017e, 0xbefe077e, 0xd4080000,
+ 0xd4090001, 0xd40c0100, 0xd40d0101, 0xf0800f00,
+ 0x00400002, 0xbefe010e, 0xbf8c0f70, 0xbf800000,
+ 0xbf800000, 0xbf800000, 0xbf800000, 0xc400180f,
+ 0x03020100, 0xbf810000
+};
+
+struct amdgpu_test_shader memcpy_ps_hang_slow_ai = {
+ memcpy_ps_hang_slow_ai_codes,
+ 7,
+ 2,
+ 9
+};
+
int amdgpu_bo_alloc_and_map_raw(amdgpu_device_handle dev, unsigned size,
unsigned alignment, unsigned heap, uint64_t alloc_flags,
uint64_t mapping_flags, amdgpu_bo_handle *bo, void **cpu,
@@ -517,6 +615,43 @@ int amdgpu_bo_alloc_and_map_raw(amdgpu_device_handle dev, unsigned size,
+CU_BOOL suite_basic_tests_enable(void)
+{
+ uint32_t asic_id;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ asic_id = device_handle->info.asic_id;
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ /* disable gfx engine basic test cases for Arturus due to no CPG */
+ if (asic_is_arcturus(asic_id)) {
+ if (amdgpu_set_test_active("Basic Tests",
+ "Command submission Test (GFX)",
+ CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n",
+ CU_get_error_msg());
+
+ if (amdgpu_set_test_active("Basic Tests",
+ "Command submission Test (Multi-Fence)",
+ CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n",
+ CU_get_error_msg());
+
+ if (amdgpu_set_test_active("Basic Tests",
+ "Sync dependency Test",
+ CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n",
+ CU_get_error_msg());
+ }
+
+ return CU_TRUE;
+}
+
int suite_basic_tests_init(void)
{
struct amdgpu_gpu_info gpu_info = {0};
@@ -1163,12 +1298,15 @@ static void amdgpu_command_submission_compute(void)
* pm4_src, resources, ib_info, and ibs_request
* submit command stream described in ibs_request and wait for this IB accomplished
*/
-static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
- unsigned ip_type,
- int instance, int pm4_dw, uint32_t *pm4_src,
- int res_cnt, amdgpu_bo_handle *resources,
- struct amdgpu_cs_ib_info *ib_info,
- struct amdgpu_cs_request *ibs_request)
+void
+amdgpu_test_exec_cs_helper_raw(amdgpu_device_handle device_handle,
+ amdgpu_context_handle context_handle,
+ unsigned ip_type, int instance, int pm4_dw,
+ uint32_t *pm4_src, int res_cnt,
+ amdgpu_bo_handle *resources,
+ struct amdgpu_cs_ib_info *ib_info,
+ struct amdgpu_cs_request *ibs_request,
+ bool secure)
{
int r;
uint32_t expired;
@@ -1200,6 +1338,8 @@ static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
ib_info->ib_mc_address = ib_result_mc_address;
ib_info->size = pm4_dw;
+ if (secure)
+ ib_info->flags |= AMDGPU_IB_FLAGS_SECURE;
ibs_request->ip_type = ip_type;
ibs_request->ring = instance;
@@ -1241,7 +1381,24 @@ static void amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
CU_ASSERT_EQUAL(r, 0);
}
-static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
+static void
+amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
+ unsigned ip_type, int instance, int pm4_dw,
+ uint32_t *pm4_src, int res_cnt,
+ amdgpu_bo_handle *resources,
+ struct amdgpu_cs_ib_info *ib_info,
+ struct amdgpu_cs_request *ibs_request)
+{
+ amdgpu_test_exec_cs_helper_raw(device_handle, context_handle,
+ ip_type, instance, pm4_dw, pm4_src,
+ res_cnt, resources, ib_info,
+ ibs_request, false);
+}
+
+void
+amdgpu_command_submission_write_linear_helper_with_secure(amdgpu_device_handle
+ device, unsigned
+ ip_type, bool secure)
{
const int sdma_write_length = 128;
const int pm4_dw = 256;
@@ -1253,6 +1410,7 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
struct amdgpu_cs_request *ibs_request;
uint64_t bo_mc;
volatile uint32_t *bo_cpu;
+ uint32_t bo_cpu_origin;
int i, j, r, loop, ring_id;
uint64_t gtt_flags[2] = {0, AMDGPU_GEM_CREATE_CPU_GTT_USWC};
amdgpu_va_handle va_handle;
@@ -1267,10 +1425,14 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
ibs_request = calloc(1, sizeof(*ibs_request));
CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
- r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &hw_ip_info);
+ r = amdgpu_query_hw_ip_info(device, ip_type, 0, &hw_ip_info);
CU_ASSERT_EQUAL(r, 0);
- r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ for (i = 0; secure && (i < 2); i++)
+ gtt_flags[i] |= AMDGPU_GEM_CREATE_ENCRYPTED;
+
+ r = amdgpu_cs_ctx_create(device, &context_handle);
+
CU_ASSERT_EQUAL(r, 0);
/* prepare resource */
@@ -1281,7 +1443,7 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
loop = 0;
while(loop < 2) {
/* allocate UC bo for sDMA use */
- r = amdgpu_bo_alloc_and_map(device_handle,
+ r = amdgpu_bo_alloc_and_map(device,
sdma_write_length * sizeof(uint32_t),
4096, AMDGPU_GEM_DOMAIN_GTT,
gtt_flags[loop], &bo, (void**)&bo_cpu,
@@ -1301,8 +1463,9 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
sdma_write_length);
else
pm4[i++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
- SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
- pm4[i++] = 0xffffffff & bo_mc;
+ SDMA_WRITE_SUB_OPCODE_LINEAR,
+ secure ? SDMA_ATOMIC_TMZ(1) : 0);
+ pm4[i++] = 0xfffffffc & bo_mc;
pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
if (family_id >= AMDGPU_FAMILY_AI)
pm4[i++] = sdma_write_length - 1;
@@ -1320,16 +1483,99 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
pm4[i++] = 0xdeadbeaf;
}
- amdgpu_test_exec_cs_helper(context_handle,
- ip_type, ring_id,
- i, pm4,
- 1, resources,
- ib_info, ibs_request);
+ amdgpu_test_exec_cs_helper_raw(device, context_handle,
+ ip_type, ring_id, i, pm4,
+ 1, resources, ib_info,
+ ibs_request, secure);
/* verify if SDMA test result meets with expected */
i = 0;
- while(i < sdma_write_length) {
- CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
+ if (!secure) {
+ while(i < sdma_write_length) {
+ CU_ASSERT_EQUAL(bo_cpu[i++], 0xdeadbeaf);
+ }
+ } else if (ip_type == AMDGPU_HW_IP_GFX) {
+ memset((void*)pm4, 0, pm4_dw * sizeof(uint32_t));
+ pm4[i++] = PACKET3(PACKET3_ATOMIC_MEM, 7);
+ /* atomic opcode for 32b w/ RTN and ATOMIC_SWAPCMP_RTN
+ * command, 1-loop_until_compare_satisfied.
+ * single_pass_atomic, 0-lru
+ * engine_sel, 0-micro_engine
+ */
+ pm4[i++] = (TC_OP_ATOMIC_CMPSWAP_RTN_32 |
+ ATOMIC_MEM_COMMAND(1) |
+ ATOMIC_MEM_CACHEPOLICAY(0) |
+ ATOMIC_MEM_ENGINESEL(0));
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = 0x12345678;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0x100;
+ amdgpu_test_exec_cs_helper_raw(device, context_handle,
+ ip_type, ring_id, i, pm4,
+ 1, resources, ib_info,
+ ibs_request, true);
+ } else if (ip_type == AMDGPU_HW_IP_DMA) {
+ /* restore the bo_cpu to compare */
+ bo_cpu_origin = bo_cpu[0];
+ memset((void*)pm4, 0, pm4_dw * sizeof(uint32_t));
+ /* atomic opcode for 32b w/ RTN and ATOMIC_SWAPCMP_RTN
+ * loop, 1-loop_until_compare_satisfied.
+ * single_pass_atomic, 0-lru
+ */
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_ATOMIC,
+ 0,
+ SDMA_ATOMIC_LOOP(1) |
+ SDMA_ATOMIC_TMZ(1) |
+ SDMA_ATOMIC_OPCODE(TC_OP_ATOMIC_CMPSWAP_RTN_32));
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = 0x12345678;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0x100;
+ amdgpu_test_exec_cs_helper_raw(device, context_handle,
+ ip_type, ring_id, i, pm4,
+ 1, resources, ib_info,
+ ibs_request, true);
+ /* DMA's atomic behavir is unlike GFX
+ * If the comparing data is not equal to destination data,
+ * For GFX, loop again till gfx timeout(system hang).
+ * For DMA, loop again till timer expired and then send interrupt.
+ * So testcase can't use interrupt mechanism.
+ * We take another way to verify. When the comparing data is not
+ * equal to destination data, overwrite the source data to the destination
+ * buffer. Otherwise, original destination data unchanged.
+ * So if the bo_cpu data is overwritten, the result is passed.
+ */
+ CU_ASSERT_NOT_EQUAL(bo_cpu[0], bo_cpu_origin);
+
+ /* compare again for the case of dest_data != cmp_data */
+ i = 0;
+ /* restore again, here dest_data should be */
+ bo_cpu_origin = bo_cpu[0];
+ memset((void*)pm4, 0, pm4_dw * sizeof(uint32_t));
+ pm4[i++] = SDMA_PACKET(SDMA_OPCODE_ATOMIC,
+ 0,
+ SDMA_ATOMIC_LOOP(1) |
+ SDMA_ATOMIC_TMZ(1) |
+ SDMA_ATOMIC_OPCODE(TC_OP_ATOMIC_CMPSWAP_RTN_32));
+ pm4[i++] = 0xfffffffc & bo_mc;
+ pm4[i++] = (0xffffffff00000000 & bo_mc) >> 32;
+ pm4[i++] = 0x87654321;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0xdeadbeaf;
+ pm4[i++] = 0x0;
+ pm4[i++] = 0x100;
+ amdgpu_test_exec_cs_helper_raw(device, context_handle,
+ ip_type, ring_id, i, pm4,
+ 1, resources, ib_info,
+ ibs_request, true);
+ /* here bo_cpu[0] should be unchanged, still is 0x12345678, otherwise failed*/
+ CU_ASSERT_EQUAL(bo_cpu[0], bo_cpu_origin);
}
r = amdgpu_bo_unmap_and_free(bo, va_handle, bo_mc,
@@ -1349,6 +1595,13 @@ static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
CU_ASSERT_EQUAL(r, 0);
}
+static void amdgpu_command_submission_write_linear_helper(unsigned ip_type)
+{
+ amdgpu_command_submission_write_linear_helper_with_secure(device_handle,
+ ip_type,
+ false);
+}
+
static void amdgpu_command_submission_sdma_write_linear(void)
{
amdgpu_command_submission_write_linear_helper(AMDGPU_HW_IP_DMA);
@@ -2054,6 +2307,37 @@ static void amdgpu_sync_dependency_test(void)
free(ibs_request.dependencies);
}
+static int amdgpu_dispatch_load_cs_shader_hang_slow(uint32_t *ptr, int family)
+{
+ struct amdgpu_test_shader *shader;
+ int i, loop = 0x10000;
+
+ switch (family) {
+ case AMDGPU_FAMILY_AI:
+ shader = &memcpy_cs_hang_slow_ai;
+ break;
+ case AMDGPU_FAMILY_RV:
+ shader = &memcpy_cs_hang_slow_rv;
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ memcpy(ptr, shader->shader, shader->header_length * sizeof(uint32_t));
+
+ for (i = 0; i < loop; i++)
+ memcpy(ptr + shader->header_length + shader->body_length * i,
+ shader->shader + shader->header_length,
+ shader->body_length * sizeof(uint32_t));
+
+ memcpy(ptr + shader->header_length + shader->body_length * loop,
+ shader->shader + shader->header_length + shader->body_length,
+ shader->foot_length * sizeof(uint32_t));
+
+ return 0;
+}
+
static int amdgpu_dispatch_load_cs_shader(uint8_t *ptr,
int cs_type)
{
@@ -2069,6 +2353,10 @@ static int amdgpu_dispatch_load_cs_shader(uint8_t *ptr,
shader = buffercopy_cs_shader_gfx9;
shader_size = sizeof(buffercopy_cs_shader_gfx9);
break;
+ case CS_HANG:
+ shader = memcpy_ps_hang;
+ shader_size = sizeof(memcpy_ps_hang);
+ break;
default:
return -1;
break;
@@ -2094,10 +2382,7 @@ static int amdgpu_dispatch_init(uint32_t *ptr, uint32_t ip_type)
ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 3);
ptr[i++] = 0x204;
i += 3;
- /* clear mmCOMPUTE_RESOURCE_LIMITS */
- ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
- ptr[i++] = 0x215;
- ptr[i++] = 0;
+
/* clear mmCOMPUTE_TMPRING_SIZE */
ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
ptr[i++] = 0x218;
@@ -2184,6 +2469,7 @@ static void amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle,
&bo_shader, &ptr_shader,
&mc_address_shader, &va_shader);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader, 0, bo_shader_size);
r = amdgpu_dispatch_load_cs_shader(ptr_shader, CS_BUFFERCLEAR);
CU_ASSERT_EQUAL(r, 0);
@@ -2220,6 +2506,11 @@ static void amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle,
ptr_cmd[i++] = 0x22222222;
ptr_cmd[i++] = 0x22222222;
+ /* clear mmCOMPUTE_RESOURCE_LIMITS */
+ ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
+ ptr_cmd[i++] = 0x215;
+ ptr_cmd[i++] = 0;
+
/* dispatch direct command */
ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3);
ptr_cmd[i++] = 0x10;
@@ -2286,7 +2577,8 @@ static void amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle,
static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
uint32_t ip_type,
- uint32_t ring)
+ uint32_t ring,
+ int hang)
{
amdgpu_context_handle context_handle;
amdgpu_bo_handle bo_src, bo_dst, bo_shader, bo_cmd, resources[4];
@@ -2302,7 +2594,8 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
int bo_cmd_size = 4096;
struct amdgpu_cs_request ibs_request = {0};
struct amdgpu_cs_ib_info ib_info= {0};
- uint32_t expired;
+ uint32_t expired, hang_state, hangs;
+ enum cs_type cs_type;
amdgpu_bo_list_handle bo_list;
struct amdgpu_cs_fence fence_status = {0};
@@ -2321,8 +2614,10 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
&bo_shader, &ptr_shader,
&mc_address_shader, &va_shader);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader, 0, bo_shader_size);
- r = amdgpu_dispatch_load_cs_shader(ptr_shader, CS_BUFFERCOPY );
+ cs_type = hang ? CS_HANG : CS_BUFFERCOPY;
+ r = amdgpu_dispatch_load_cs_shader(ptr_shader, cs_type);
CU_ASSERT_EQUAL(r, 0);
r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096,
@@ -2365,6 +2660,11 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
ptr_cmd[i++] = 0x400;
ptr_cmd[i++] = 0x74fac;
+ /* clear mmCOMPUTE_RESOURCE_LIMITS */
+ ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
+ ptr_cmd[i++] = 0x215;
+ ptr_cmd[i++] = 0;
+
/* dispatch direct command */
ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3);
ptr_cmd[i++] = 0x10;
@@ -2403,14 +2703,21 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
r = amdgpu_cs_query_fence_status(&fence_status,
AMDGPU_TIMEOUT_INFINITE,
0, &expired);
- CU_ASSERT_EQUAL(r, 0);
- CU_ASSERT_EQUAL(expired, true);
- /* verify if memcpy test result meets with expected */
- i = 0;
- while(i < bo_dst_size) {
- CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]);
- i++;
+ if (!hang) {
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
+
+ /* verify if memcpy test result meets with expected */
+ i = 0;
+ while(i < bo_dst_size) {
+ CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]);
+ i++;
+ }
+ } else {
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
}
r = amdgpu_bo_list_destroy(bo_list);
@@ -2430,7 +2737,8 @@ static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle,
r = amdgpu_cs_ctx_free(context_handle);
CU_ASSERT_EQUAL(r, 0);
}
-static void amdgpu_dispatch_test(void)
+
+static void amdgpu_compute_dispatch_test(void)
{
int r;
struct drm_amdgpu_info_hw_ip info;
@@ -2438,21 +2746,248 @@ static void amdgpu_dispatch_test(void)
r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_COMPUTE, 0, &info);
CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no compute ring\n");
for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
amdgpu_memset_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id);
- amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id);
+ amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id, 0);
}
+}
+
+static void amdgpu_gfx_dispatch_test(void)
+{
+ int r;
+ struct drm_amdgpu_info_hw_ip info;
+ uint32_t ring_id;
r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no graphics ring\n");
for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
amdgpu_memset_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id);
- amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id);
+ amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id, 0);
+ }
+}
+
+void amdgpu_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip_type)
+{
+ int r;
+ struct drm_amdgpu_info_hw_ip info;
+ uint32_t ring_id;
+
+ r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no ring for ip %d\n", ip_type);
+
+ for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
+ amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0);
+ amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 1);
+ amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0);
}
}
+static void amdgpu_memcpy_dispatch_hang_slow_test(amdgpu_device_handle device_handle,
+ uint32_t ip_type, uint32_t ring)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle bo_src, bo_dst, bo_shader, bo_cmd, resources[4];
+ volatile unsigned char *ptr_dst;
+ void *ptr_shader;
+ unsigned char *ptr_src;
+ uint32_t *ptr_cmd;
+ uint64_t mc_address_src, mc_address_dst, mc_address_shader, mc_address_cmd;
+ amdgpu_va_handle va_src, va_dst, va_shader, va_cmd;
+ int i, r;
+ int bo_dst_size = 0x4000000;
+ int bo_shader_size = 0x400000;
+ int bo_cmd_size = 4096;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info= {0};
+ uint32_t hang_state, hangs, expired;
+ struct amdgpu_gpu_info gpu_info = {0};
+ amdgpu_bo_list_handle bo_list;
+ struct amdgpu_cs_fence fence_status = {0};
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &bo_cmd, (void **)&ptr_cmd,
+ &mc_address_cmd, &va_cmd);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_cmd, 0, bo_cmd_size);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0,
+ &bo_shader, &ptr_shader,
+ &mc_address_shader, &va_shader);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader, 0, bo_shader_size);
+
+ r = amdgpu_dispatch_load_cs_shader_hang_slow(ptr_shader, gpu_info.family_id);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0,
+ &bo_src, (void **)&ptr_src,
+ &mc_address_src, &va_src);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0,
+ &bo_dst, (void **)&ptr_dst,
+ &mc_address_dst, &va_dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(ptr_src, 0x55, bo_dst_size);
+
+ i = 0;
+ i += amdgpu_dispatch_init(ptr_cmd + i, ip_type);
+
+ /* Issue commands to set cu mask used in current dispatch */
+ i += amdgpu_dispatch_write_cumask(ptr_cmd + i);
+
+ /* Writes shader state to HW */
+ i += amdgpu_dispatch_write2hw(ptr_cmd + i, mc_address_shader);
+
+ /* Write constant data */
+ /* Writes the texture resource constants data to the SGPRs */
+ ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4);
+ ptr_cmd[i++] = 0x240;
+ ptr_cmd[i++] = mc_address_src;
+ ptr_cmd[i++] = (mc_address_src >> 32) | 0x100000;
+ ptr_cmd[i++] = 0x400000;
+ ptr_cmd[i++] = 0x74fac;
+
+ /* Writes the UAV constant data to the SGPRs. */
+ ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4);
+ ptr_cmd[i++] = 0x244;
+ ptr_cmd[i++] = mc_address_dst;
+ ptr_cmd[i++] = (mc_address_dst >> 32) | 0x100000;
+ ptr_cmd[i++] = 0x400000;
+ ptr_cmd[i++] = 0x74fac;
+
+ /* clear mmCOMPUTE_RESOURCE_LIMITS */
+ ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1);
+ ptr_cmd[i++] = 0x215;
+ ptr_cmd[i++] = 0;
+
+ /* dispatch direct command */
+ ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3);
+ ptr_cmd[i++] = 0x10000;
+ ptr_cmd[i++] = 1;
+ ptr_cmd[i++] = 1;
+ ptr_cmd[i++] = 1;
+
+ while (i & 7)
+ ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */
+
+ resources[0] = bo_shader;
+ resources[1] = bo_src;
+ resources[2] = bo_dst;
+ resources[3] = bo_cmd;
+ r = amdgpu_bo_list_create(device_handle, 4, resources, NULL, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ib_info.ib_mc_address = mc_address_cmd;
+ ib_info.size = i;
+ ibs_request.ip_type = ip_type;
+ ibs_request.ring = ring;
+ ibs_request.resources = bo_list;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.ip_type = ip_type;
+ fence_status.ip_instance = 0;
+ fence_status.ring = ring;
+ fence_status.context = context_handle;
+ fence_status.fence = ibs_request.seq_no;
+
+ /* wait for IB accomplished */
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(bo_src, va_src, mc_address_src, bo_dst_size);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_dst_size);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(bo_shader, va_shader, mc_address_shader, bo_shader_size);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+void amdgpu_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip_type)
+{
+ int r;
+ struct drm_amdgpu_info_hw_ip info;
+ uint32_t ring_id;
+
+ r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no ring for ip %d\n", ip_type);
+
+ for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
+ amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0);
+ amdgpu_memcpy_dispatch_hang_slow_test(device_handle, ip_type, ring_id);
+ amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0);
+ }
+}
+
+static int amdgpu_draw_load_ps_shader_hang_slow(uint32_t *ptr, int family)
+{
+ struct amdgpu_test_shader *shader;
+ int i, loop = 0x40000;
+
+ switch (family) {
+ case AMDGPU_FAMILY_AI:
+ case AMDGPU_FAMILY_RV:
+ shader = &memcpy_ps_hang_slow_ai;
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ memcpy(ptr, shader->shader, shader->header_length * sizeof(uint32_t));
+
+ for (i = 0; i < loop; i++)
+ memcpy(ptr + shader->header_length + shader->body_length * i,
+ shader->shader + shader->header_length,
+ shader->body_length * sizeof(uint32_t));
+
+ memcpy(ptr + shader->header_length + shader->body_length * loop,
+ shader->shader + shader->header_length + shader->body_length,
+ shader->foot_length * sizeof(uint32_t));
+
+ return 0;
+}
+
static int amdgpu_draw_load_ps_shader(uint8_t *ptr, int ps_type)
{
int i;
@@ -2478,6 +3013,12 @@ static int amdgpu_draw_load_ps_shader(uint8_t *ptr, int ps_type)
patchinfo_code_size = ps_tex_shader_patchinfo_code_size_gfx9;
patchcode_offset = ps_tex_shader_patchinfo_offset_gfx9;
break;
+ case PS_HANG:
+ shader = memcpy_ps_hang;
+ shader_size = sizeof(memcpy_ps_hang);
+
+ memcpy(ptr, shader, shader_size);
+ return 0;
default:
return -1;
break;
@@ -2534,7 +3075,8 @@ static int amdgpu_draw_init(uint32_t *ptr)
}
static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr,
- uint64_t dst_addr)
+ uint64_t dst_addr,
+ int hang_slow)
{
int i = 0;
@@ -2559,7 +3101,7 @@ static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr,
ptr[i++] = 0x318;
ptr[i++] = dst_addr >> 8;
ptr[i++] = dst_addr >> 40;
- ptr[i++] = 0x7c01f;
+ ptr[i++] = hang_slow ? 0x1ffc7ff : 0x7c01f;
ptr[i++] = 0;
ptr[i++] = 0x50438;
ptr[i++] = 0x10140000;
@@ -2568,7 +3110,7 @@ static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr,
/* mmCB_MRT0_EPITCH */
ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
ptr[i++] = 0x1e8;
- ptr[i++] = 0x1f;
+ ptr[i++] = hang_slow ? 0x7ff : 0x1f;
/* 0xA32B CB_COLOR1_BASE */
ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
@@ -2594,7 +3136,7 @@ static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr,
return i;
}
-static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr)
+static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr, int hang_slow)
{
int i = 0;
const uint32_t *cached_cmd_ptr;
@@ -2626,6 +3168,8 @@ static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr)
cached_cmd_size = sizeof(cached_cmd_gfx9);
memcpy(ptr + i, cached_cmd_ptr, cached_cmd_size);
+ if (hang_slow)
+ *(ptr + i + 12) = 0x8000800;
i += cached_cmd_size/sizeof(uint32_t);
return i;
@@ -2633,7 +3177,8 @@ static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr)
static int amdgpu_draw_vs_RectPosTexFast_write2hw(uint32_t *ptr,
int ps_type,
- uint64_t shader_addr)
+ uint64_t shader_addr,
+ int hang_slow)
{
int i = 0;
@@ -2675,8 +3220,8 @@ static int amdgpu_draw_vs_RectPosTexFast_write2hw(uint32_t *ptr,
ptr[i++] = PACKET3(PKT3_SET_SH_REG, 4);
ptr[i++] = 0x4c;
i += 2;
- ptr[i++] = 0x42000000;
- ptr[i++] = 0x42000000;
+ ptr[i++] = hang_slow ? 0x45000000 : 0x42000000;
+ ptr[i++] = hang_slow ? 0x45000000 : 0x42000000;
ptr[i++] = PACKET3(PKT3_SET_SH_REG, 4);
ptr[i++] = 0x50;
@@ -2813,11 +3358,11 @@ void amdgpu_memset_draw(amdgpu_device_handle device_handle,
i = 0;
i += amdgpu_draw_init(ptr_cmd + i);
- i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst);
+ i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 0);
- i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i);
+ i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 0);
- i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_CONST, mc_address_shader_vs);
+ i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_CONST, mc_address_shader_vs, 0);
i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_CONST, mc_address_shader_ps);
@@ -2837,7 +3382,7 @@ void amdgpu_memset_draw(amdgpu_device_handle device_handle,
resources[1] = bo_shader_ps;
resources[2] = bo_shader_vs;
resources[3] = bo_cmd;
- r = amdgpu_bo_list_create(device_handle, 3, resources, NULL, &bo_list);
+ r = amdgpu_bo_list_create(device_handle, 4, resources, NULL, &bo_list);
CU_ASSERT_EQUAL(r, 0);
ib_info.ib_mc_address = mc_address_cmd;
@@ -2901,12 +3446,14 @@ static void amdgpu_memset_draw_test(amdgpu_device_handle device_handle,
&bo_shader_ps, &ptr_shader_ps,
&mc_address_shader_ps, &va_shader_ps);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_ps, 0, bo_shader_size);
r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096,
AMDGPU_GEM_DOMAIN_VRAM, 0,
&bo_shader_vs, &ptr_shader_vs,
&mc_address_shader_vs, &va_shader_vs);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_vs, 0, bo_shader_size);
r = amdgpu_draw_load_ps_shader(ptr_shader_ps, PS_CONST);
CU_ASSERT_EQUAL(r, 0);
@@ -2929,7 +3476,7 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle,
amdgpu_bo_handle bo_shader_vs,
uint64_t mc_address_shader_ps,
uint64_t mc_address_shader_vs,
- uint32_t ring)
+ uint32_t ring, int hang)
{
amdgpu_context_handle context_handle;
amdgpu_bo_handle bo_dst, bo_src, bo_cmd, resources[5];
@@ -2943,7 +3490,8 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle,
int bo_cmd_size = 4096;
struct amdgpu_cs_request ibs_request = {0};
struct amdgpu_cs_ib_info ib_info= {0};
- uint32_t hang_state, hangs, expired;
+ uint32_t hang_state, hangs;
+ uint32_t expired;
amdgpu_bo_list_handle bo_list;
struct amdgpu_cs_fence fence_status = {0};
@@ -2974,11 +3522,11 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle,
i = 0;
i += amdgpu_draw_init(ptr_cmd + i);
- i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst);
+ i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 0);
- i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i);
+ i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 0);
- i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_vs);
+ i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_vs, 0);
i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_ps);
@@ -2996,7 +3544,7 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle,
ptr_cmd[i++] = 0x92;
i += 3;
- ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 1);
+ ptr_cmd[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
ptr_cmd[i++] = 0x191;
ptr_cmd[i++] = 0;
@@ -3034,14 +3582,20 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle,
r = amdgpu_cs_query_fence_status(&fence_status,
AMDGPU_TIMEOUT_INFINITE,
0, &expired);
- CU_ASSERT_EQUAL(r, 0);
- CU_ASSERT_EQUAL(expired, true);
+ if (!hang) {
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(expired, true);
- /* verify if memcpy test result meets with expected */
- i = 0;
- while(i < bo_size) {
- CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]);
- i++;
+ /* verify if memcpy test result meets with expected */
+ i = 0;
+ while(i < bo_size) {
+ CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]);
+ i++;
+ }
+ } else {
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
}
r = amdgpu_bo_list_destroy(bo_list);
@@ -3059,7 +3613,8 @@ static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle,
CU_ASSERT_EQUAL(r, 0);
}
-static void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t ring)
+void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t ring,
+ int hang)
{
amdgpu_bo_handle bo_shader_ps, bo_shader_vs;
void *ptr_shader_ps;
@@ -3067,6 +3622,7 @@ static void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t
uint64_t mc_address_shader_ps, mc_address_shader_vs;
amdgpu_va_handle va_shader_ps, va_shader_vs;
int bo_shader_size = 4096;
+ enum ps_type ps_type = hang ? PS_HANG : PS_TEX;
int r;
r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096,
@@ -3074,21 +3630,23 @@ static void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t
&bo_shader_ps, &ptr_shader_ps,
&mc_address_shader_ps, &va_shader_ps);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_ps, 0, bo_shader_size);
r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096,
AMDGPU_GEM_DOMAIN_VRAM, 0,
&bo_shader_vs, &ptr_shader_vs,
&mc_address_shader_vs, &va_shader_vs);
CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_vs, 0, bo_shader_size);
- r = amdgpu_draw_load_ps_shader(ptr_shader_ps, PS_TEX);
+ r = amdgpu_draw_load_ps_shader(ptr_shader_ps, ps_type);
CU_ASSERT_EQUAL(r, 0);
r = amdgpu_draw_load_vs_shader(ptr_shader_vs);
CU_ASSERT_EQUAL(r, 0);
amdgpu_memcpy_draw(device_handle, bo_shader_ps, bo_shader_vs,
- mc_address_shader_ps, mc_address_shader_vs, ring);
+ mc_address_shader_ps, mc_address_shader_vs, ring, hang);
r = amdgpu_bo_unmap_and_free(bo_shader_ps, va_shader_ps, mc_address_shader_ps, bo_shader_size);
CU_ASSERT_EQUAL(r, 0);
@@ -3105,9 +3663,207 @@ static void amdgpu_draw_test(void)
r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no graphics ring\n");
for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
amdgpu_memset_draw_test(device_handle, ring_id);
- amdgpu_memcpy_draw_test(device_handle, ring_id);
+ amdgpu_memcpy_draw_test(device_handle, ring_id, 0);
}
}
+
+void amdgpu_memcpy_draw_hang_slow_test(amdgpu_device_handle device_handle, uint32_t ring)
+{
+ amdgpu_context_handle context_handle;
+ amdgpu_bo_handle bo_shader_ps, bo_shader_vs;
+ amdgpu_bo_handle bo_dst, bo_src, bo_cmd, resources[5];
+ void *ptr_shader_ps;
+ void *ptr_shader_vs;
+ volatile unsigned char *ptr_dst;
+ unsigned char *ptr_src;
+ uint32_t *ptr_cmd;
+ uint64_t mc_address_dst, mc_address_src, mc_address_cmd;
+ uint64_t mc_address_shader_ps, mc_address_shader_vs;
+ amdgpu_va_handle va_shader_ps, va_shader_vs;
+ amdgpu_va_handle va_dst, va_src, va_cmd;
+ struct amdgpu_gpu_info gpu_info = {0};
+ int i, r;
+ int bo_size = 0x4000000;
+ int bo_shader_ps_size = 0x400000;
+ int bo_shader_vs_size = 4096;
+ int bo_cmd_size = 4096;
+ struct amdgpu_cs_request ibs_request = {0};
+ struct amdgpu_cs_ib_info ib_info= {0};
+ uint32_t hang_state, hangs, expired;
+ amdgpu_bo_list_handle bo_list;
+ struct amdgpu_cs_fence fence_status = {0};
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096,
+ AMDGPU_GEM_DOMAIN_GTT, 0,
+ &bo_cmd, (void **)&ptr_cmd,
+ &mc_address_cmd, &va_cmd);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_cmd, 0, bo_cmd_size);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_ps_size, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0,
+ &bo_shader_ps, &ptr_shader_ps,
+ &mc_address_shader_ps, &va_shader_ps);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_ps, 0, bo_shader_ps_size);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_vs_size, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0,
+ &bo_shader_vs, &ptr_shader_vs,
+ &mc_address_shader_vs, &va_shader_vs);
+ CU_ASSERT_EQUAL(r, 0);
+ memset(ptr_shader_vs, 0, bo_shader_vs_size);
+
+ r = amdgpu_draw_load_ps_shader_hang_slow(ptr_shader_ps, gpu_info.family_id);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_draw_load_vs_shader(ptr_shader_vs);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0,
+ &bo_src, (void **)&ptr_src,
+ &mc_address_src, &va_src);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM, 0,
+ &bo_dst, (void **)&ptr_dst,
+ &mc_address_dst, &va_dst);
+ CU_ASSERT_EQUAL(r, 0);
+
+ memset(ptr_src, 0x55, bo_size);
+
+ i = 0;
+ i += amdgpu_draw_init(ptr_cmd + i);
+
+ i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 1);
+
+ i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 1);
+
+ i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_TEX,
+ mc_address_shader_vs, 1);
+
+ i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_ps);
+
+ ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 8);
+ ptr_cmd[i++] = 0xc;
+ ptr_cmd[i++] = mc_address_src >> 8;
+ ptr_cmd[i++] = mc_address_src >> 40 | 0x10e00000;
+ ptr_cmd[i++] = 0x1ffc7ff;
+ ptr_cmd[i++] = 0x90500fac;
+ ptr_cmd[i++] = 0xffe000;
+ i += 3;
+
+ ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 4);
+ ptr_cmd[i++] = 0x14;
+ ptr_cmd[i++] = 0x92;
+ i += 3;
+
+ ptr_cmd[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1);
+ ptr_cmd[i++] = 0x191;
+ ptr_cmd[i++] = 0;
+
+ i += amdgpu_draw_draw(ptr_cmd + i);
+
+ while (i & 7)
+ ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */
+
+ resources[0] = bo_dst;
+ resources[1] = bo_src;
+ resources[2] = bo_shader_ps;
+ resources[3] = bo_shader_vs;
+ resources[4] = bo_cmd;
+ r = amdgpu_bo_list_create(device_handle, 5, resources, NULL, &bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ ib_info.ib_mc_address = mc_address_cmd;
+ ib_info.size = i;
+ ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ring = ring;
+ ibs_request.resources = bo_list;
+ ibs_request.number_of_ibs = 1;
+ ibs_request.ibs = &ib_info;
+ ibs_request.fence_info.handle = NULL;
+ r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
+ CU_ASSERT_EQUAL(r, 0);
+
+ fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_instance = 0;
+ fence_status.ring = ring;
+ fence_status.context = context_handle;
+ fence_status.fence = ibs_request.seq_no;
+
+ /* wait for IB accomplished */
+ r = amdgpu_cs_query_fence_status(&fence_status,
+ AMDGPU_TIMEOUT_INFINITE,
+ 0, &expired);
+
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
+
+ r = amdgpu_bo_list_destroy(bo_list);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_size);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_unmap_and_free(bo_src, va_src, mc_address_src, bo_size);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_bo_unmap_and_free(bo_shader_ps, va_shader_ps, mc_address_shader_ps, bo_shader_ps_size);
+ CU_ASSERT_EQUAL(r, 0);
+ r = amdgpu_bo_unmap_and_free(bo_shader_vs, va_shader_vs, mc_address_shader_vs, bo_shader_vs_size);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_gpu_reset_test(void)
+{
+ int r;
+ char debugfs_path[256], tmp[10];
+ int fd;
+ struct stat sbuf;
+ amdgpu_context_handle context_handle;
+ uint32_t hang_state, hangs;
+
+ r = amdgpu_cs_ctx_create(device_handle, &context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ r = fstat(drm_amdgpu[0], &sbuf);
+ CU_ASSERT_EQUAL(r, 0);
+
+ sprintf(debugfs_path, "/sys/kernel/debug/dri/%d/amdgpu_gpu_recover", minor(sbuf.st_rdev));
+ fd = open(debugfs_path, O_RDONLY);
+ CU_ASSERT(fd >= 0);
+
+ r = read(fd, tmp, sizeof(tmp)/sizeof(char));
+ CU_ASSERT(r > 0);
+
+ r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs);
+ CU_ASSERT_EQUAL(r, 0);
+ CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET);
+
+ close(fd);
+ r = amdgpu_cs_ctx_free(context_handle);
+ CU_ASSERT_EQUAL(r, 0);
+
+ amdgpu_compute_dispatch_test();
+ amdgpu_gfx_dispatch_test();
+}
diff --git a/tests/amdgpu/bo_tests.c b/tests/amdgpu/bo_tests.c
index 7cff4cf7..4c11665a 100644
--- a/tests/amdgpu/bo_tests.c
+++ b/tests/amdgpu/bo_tests.c
@@ -267,7 +267,6 @@ static void amdgpu_memory_alloc(void)
static void amdgpu_mem_fail_alloc(void)
{
- amdgpu_bo_handle bo;
int r;
struct amdgpu_bo_alloc_request req = {0};
amdgpu_bo_handle buf_handle;
@@ -282,7 +281,7 @@ static void amdgpu_mem_fail_alloc(void)
CU_ASSERT_EQUAL(r, -ENOMEM);
if (!r) {
- r = amdgpu_bo_free(bo);
+ r = amdgpu_bo_free(buf_handle);
CU_ASSERT_EQUAL(r, 0);
}
}
diff --git a/tests/amdgpu/cs_tests.c b/tests/amdgpu/cs_tests.c
index 7ad0f0dc..10124c15 100644
--- a/tests/amdgpu/cs_tests.c
+++ b/tests/amdgpu/cs_tests.c
@@ -64,17 +64,21 @@ CU_TestInfo cs_tests[] = {
CU_BOOL suite_cs_tests_enable(void)
{
+ uint32_t asic_id;
+
if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
&minor_version, &device_handle))
return CU_FALSE;
family_id = device_handle->info.family_id;
+ asic_id = device_handle->info.asic_id;
if (amdgpu_device_deinitialize(device_handle))
return CU_FALSE;
- if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI) {
+ if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI ||
+ asic_is_arcturus(asic_id)) {
printf("\n\nThe ASIC NOT support UVD, suite disabled\n");
return CU_FALSE;
}
@@ -358,6 +362,7 @@ static void amdgpu_cs_uvd_decode(void)
bs_addr = fb_addr + 4*1024;
dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
+ ctx_addr = 0;
if (family_id >= AMDGPU_FAMILY_VI) {
if ((family_id == AMDGPU_FAMILY_AI) ||
(chip_id == chip_rev+0x50 || chip_id == chip_rev+0x5A ||
diff --git a/tests/amdgpu/deadlock_tests.c b/tests/amdgpu/deadlock_tests.c
index 91368c15..248cc339 100644
--- a/tests/amdgpu/deadlock_tests.c
+++ b/tests/amdgpu/deadlock_tests.c
@@ -24,7 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#ifdef HAVE_ALLOCA_H
+#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
@@ -114,10 +114,17 @@ static void amdgpu_deadlock_compute(void);
static void amdgpu_illegal_reg_access();
static void amdgpu_illegal_mem_access();
static void amdgpu_deadlock_sdma(void);
+static void amdgpu_dispatch_hang_gfx(void);
+static void amdgpu_dispatch_hang_compute(void);
+static void amdgpu_dispatch_hang_slow_gfx(void);
+static void amdgpu_dispatch_hang_slow_compute(void);
+static void amdgpu_draw_hang_gfx(void);
+static void amdgpu_draw_hang_slow_gfx(void);
CU_BOOL suite_deadlock_tests_enable(void)
{
CU_BOOL enable = CU_TRUE;
+ uint32_t asic_id;
if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
&minor_version, &device_handle))
@@ -134,6 +141,15 @@ CU_BOOL suite_deadlock_tests_enable(void)
enable = CU_FALSE;
}
+ asic_id = device_handle->info.asic_id;
+ if (asic_is_arcturus(asic_id)) {
+ if (amdgpu_set_test_active("Deadlock Tests",
+ "gfx ring block test (set amdgpu.lockup_timeout=50)",
+ CU_FALSE))
+ fprintf(stderr, "test deactivation failed - %s\n",
+ CU_get_error_msg());
+ }
+
if (device_handle->info.family_id >= AMDGPU_FAMILY_AI)
use_uc_mtype = 1;
@@ -178,6 +194,12 @@ CU_TestInfo deadlock_tests[] = {
{ "sdma ring block test (set amdgpu.lockup_timeout=50)", amdgpu_deadlock_sdma },
{ "illegal reg access test", amdgpu_illegal_reg_access },
{ "illegal mem access test (set amdgpu.vm_fault_stop=2)", amdgpu_illegal_mem_access },
+ { "gfx ring bad dispatch test (set amdgpu.lockup_timeout=50)", amdgpu_dispatch_hang_gfx },
+ { "compute ring bad dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_compute },
+ { "gfx ring bad slow dispatch test (set amdgpu.lockup_timeout=50)", amdgpu_dispatch_hang_slow_gfx },
+ { "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_slow_compute },
+ { "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_gfx },
+ { "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_slow_gfx },
CU_TEST_INFO_NULL,
};
@@ -478,3 +500,57 @@ static void amdgpu_illegal_mem_access()
{
bad_access_helper(0);
}
+
+static void amdgpu_dispatch_hang_gfx(void)
+{
+ amdgpu_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_dispatch_hang_compute(void)
+{
+ amdgpu_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_COMPUTE);
+}
+
+static void amdgpu_dispatch_hang_slow_gfx(void)
+{
+ amdgpu_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_GFX);
+}
+
+static void amdgpu_dispatch_hang_slow_compute(void)
+{
+ amdgpu_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_COMPUTE);
+}
+
+static void amdgpu_draw_hang_gfx(void)
+{
+ int r;
+ struct drm_amdgpu_info_hw_ip info;
+ uint32_t ring_id;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+ if (!info.available_rings)
+ printf("SKIP ... as there's no graphic ring\n");
+
+ for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
+ amdgpu_memcpy_draw_test(device_handle, ring_id, 0);
+ amdgpu_memcpy_draw_test(device_handle, ring_id, 1);
+ amdgpu_memcpy_draw_test(device_handle, ring_id, 0);
+ }
+}
+
+static void amdgpu_draw_hang_slow_gfx(void)
+{
+ struct drm_amdgpu_info_hw_ip info;
+ uint32_t ring_id;
+ int r;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) {
+ amdgpu_memcpy_draw_test(device_handle, ring_id, 0);
+ amdgpu_memcpy_draw_hang_slow_test(device_handle, ring_id);
+ amdgpu_memcpy_draw_test(device_handle, ring_id, 0);
+ }
+}
diff --git a/tests/amdgpu/decode_messages.h b/tests/amdgpu/decode_messages.h
index bd6fe4b6..ee1deb4f 100644
--- a/tests/amdgpu/decode_messages.h
+++ b/tests/amdgpu/decode_messages.h
@@ -361,7 +361,7 @@ static const uint8_t uvd_decode_msg[] = {
};
static const uint8_t avc_decode_msg[] = {
- 0x02,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x88,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x85,0x00,0x00,0x00,0x88,0x00,0x00,0x00,
0x01,0x00,0x00,0x01,0x00,0x03,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
@@ -826,7 +826,7 @@ static const uint8_t vcn_dec_decode_msg[] = {
0x28,0x00,0x00,0x00,0x90,0x06,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
0x03,0x00,0x44,0x40,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xec,0x00,0x00,0x00,
- 0x5c,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x5c,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x60,0x03,0x00,0x00,0xe0,0x01,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x94,0x6b,0x00,
0x96,0x4e,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x50,0x00,
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
@@ -845,4 +845,10 @@ static const uint8_t vcn_dec_destroy_msg[] = {
0x03,0x00,0x44,0x40,0x00,0x00,0x00,0x00,
};
+static const uint8_t feedback_msg[] = {
+ 0x2c,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
#endif /* _DECODE_MESSAGES_H_ */
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 1726cb43..eb16a50c 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -24,9 +24,9 @@ if dep_cunit.found()
files(
'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c',
'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c',
- 'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c',
+ 'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c', 'security_tests.c',
),
- dependencies : [dep_cunit, dep_threads],
+ dependencies : [dep_cunit, dep_threads, dep_atomic_ops],
include_directories : [inc_root, inc_drm, include_directories('../../amdgpu')],
link_with : [libdrm, libdrm_amdgpu],
install : with_install_tests,
diff --git a/tests/amdgpu/ras_tests.c b/tests/amdgpu/ras_tests.c
index 81c34ad6..810bf172 100644
--- a/tests/amdgpu/ras_tests.c
+++ b/tests/amdgpu/ras_tests.c
@@ -30,6 +30,11 @@
#include <fcntl.h>
#include <stdio.h>
#include "xf86drm.h"
+#include <limits.h>
+
+#define PATH_SIZE PATH_MAX
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
const char *ras_block_string[] = {
"umc",
@@ -72,11 +77,251 @@ enum amdgpu_ras_block {
#define AMDGPU_RAS_BLOCK_COUNT AMDGPU_RAS_BLOCK__LAST
#define AMDGPU_RAS_BLOCK_MASK ((1ULL << AMDGPU_RAS_BLOCK_COUNT) - 1)
+enum amdgpu_ras_gfx_subblock {
+ /* CPC */
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_START = 0,
+ AMDGPU_RAS_BLOCK__GFX_CPC_SCRATCH =
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPC_UCODE,
+ AMDGPU_RAS_BLOCK__GFX_DC_STATE_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_CSINVOC_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME1,
+ AMDGPU_RAS_BLOCK__GFX_DC_STATE_ME2,
+ AMDGPU_RAS_BLOCK__GFX_DC_CSINVOC_ME2,
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME2,
+ AMDGPU_RAS_BLOCK__GFX_CPC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_DC_RESTORE_ME2,
+ /* CPF */
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPF_ROQ_ME2 =
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPF_ROQ_ME1,
+ AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPF_INDEX_END = AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ /* CPG */
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPG_DMA_ROQ =
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_CPG_DMA_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ AMDGPU_RAS_BLOCK__GFX_CPG_INDEX_END = AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ /* GDS */
+ AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_GDS_MEM = AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_GDS_INPUT_QUEUE,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PHY_CMD_RAM_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PHY_DATA_RAM_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PIPE_MEM,
+ AMDGPU_RAS_BLOCK__GFX_GDS_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_GDS_OA_PIPE_MEM,
+ /* SPI */
+ AMDGPU_RAS_BLOCK__GFX_SPI_SR_MEM,
+ /* SQ */
+ AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQ_SGPR = AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQ_LDS_D,
+ AMDGPU_RAS_BLOCK__GFX_SQ_LDS_I,
+ AMDGPU_RAS_BLOCK__GFX_SQ_VGPR,
+ AMDGPU_RAS_BLOCK__GFX_SQ_INDEX_END = AMDGPU_RAS_BLOCK__GFX_SQ_VGPR,
+ /* SQC (3 ranges) */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_START,
+ /* SQC range 0 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_UTCL1_LFIFO =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU0_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU0_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_WRITE_DATA_BUF,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_UTCL1_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU2_UTCL1_LFIFO,
+ /* SQC range 1 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_TAG_RAM =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_UTCL1_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_TAG_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_HIT_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_DIRTY_BIT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKA_BANK_RAM,
+ /* SQC range 2 */
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_TAG_RAM =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_UTCL1_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_TAG_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_HIT_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_MISS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_DIRTY_BIT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_DATA_BANKB_BANK_RAM,
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_SQC_INDEX2_END,
+ /* TA */
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_DFIFO =
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_AFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FL_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FX_LFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_FS_CFIFO,
+ AMDGPU_RAS_BLOCK__GFX_TA_INDEX_END = AMDGPU_RAS_BLOCK__GFX_TA_FS_CFIFO,
+ /* TCA */
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCA_HOLE_FIFO =
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCA_REQ_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCA_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCA_REQ_FIFO,
+ /* TCC (5 sub-ranges) */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_START,
+ /* TCC range 0 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_0_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_0,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DIRTY_BANK_0,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DIRTY_BANK_1,
+ AMDGPU_RAS_BLOCK__GFX_TCC_HIGH_RATE_TAG,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LOW_RATE_TAG,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_LOW_RATE_TAG,
+ /* TCC range 1 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_DEC =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_TRANSFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_IN_USE_TRANSFER,
+ /* TCC range 2 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_RETURN_DATA =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_RETURN_CONTROL,
+ AMDGPU_RAS_BLOCK__GFX_TCC_UC_ATOMIC_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRITE_RETURN,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRITE_CACHE_READ,
+ AMDGPU_RAS_BLOCK__GFX_TCC_SRC_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_SRC_FIFO_NEXT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_TAG_PROBE_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_TAG_PROBE_FIFO,
+ /* TCC range 3 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO_NEXT_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX3_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_LATENCY_FIFO_NEXT_RAM,
+ /* TCC range 4 */
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_WRRET_TAG_WRITE_RETURN =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_START,
+ AMDGPU_RAS_BLOCK__GFX_TCC_ATOMIC_RETURN_BUFFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_ATOMIC_RETURN_BUFFER,
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCC_INDEX4_END,
+ /* TCI */
+ AMDGPU_RAS_BLOCK__GFX_TCI_WRITE_RAM,
+ /* TCP */
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCP_CACHE_RAM =
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TCP_LFIFO_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCP_CMD_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCP_VM_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TCP_DB_RAM,
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO0,
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO1,
+ AMDGPU_RAS_BLOCK__GFX_TCP_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_TCP_UTCL1_LFIFO1,
+ /* TD */
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_LO =
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_HI,
+ AMDGPU_RAS_BLOCK__GFX_TD_CS_FIFO,
+ AMDGPU_RAS_BLOCK__GFX_TD_INDEX_END = AMDGPU_RAS_BLOCK__GFX_TD_CS_FIFO,
+ /* EA (3 sub-ranges) */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_START,
+ /* EA range 0 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_START =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_CMDMEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_RRET_TAGMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_WRET_TAGMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIRD_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX0_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_DATAMEM,
+ /* EA range 1 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_PAGEMEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_DRAMWR_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IORD_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IOWR_CMDMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_IOWR_DATAMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIRD_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_PAGEMEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX1_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_GMIWR_PAGEMEM,
+ /* EA range 2 */
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D0MEM =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_START,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D1MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D2MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D3MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_MAM_D3MEM,
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX_END =
+ AMDGPU_RAS_BLOCK__GFX_EA_INDEX2_END,
+ /* UTC VM L2 bank */
+ AMDGPU_RAS_BLOCK__UTC_VML2_BANK_CACHE,
+ /* UTC VM walker */
+ AMDGPU_RAS_BLOCK__UTC_VML2_WALKER,
+ /* UTC ATC L2 2MB cache */
+ AMDGPU_RAS_BLOCK__UTC_ATCL2_CACHE_2M_BANK,
+ /* UTC ATC L2 4KB cache */
+ AMDGPU_RAS_BLOCK__UTC_ATCL2_CACHE_4K_BANK,
+ AMDGPU_RAS_BLOCK__GFX_MAX
+};
+
enum amdgpu_ras_error_type {
- AMDGPU_RAS_ERROR__NONE = 0,
- AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE = 2,
- AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE = 4,
- AMDGPU_RAS_ERROR__POISON = 8,
+ AMDGPU_RAS_ERROR__NONE = 0,
+ AMDGPU_RAS_ERROR__PARITY = 1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE = 2,
+ AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE = 4,
+ AMDGPU_RAS_ERROR__POISON = 8,
+};
+
+struct ras_inject_test_config {
+ char name[64];
+ char block[32];
+ int sub_block;
+ enum amdgpu_ras_error_type type;
+ uint64_t address;
+ uint64_t value;
};
struct ras_common_if {
@@ -100,8 +345,10 @@ struct ras_debug_if {
int op;
};
/* for now, only umc, gfx, sdma has implemented. */
-#define DEFAULT_RAS_BLOCK_MASK_INJECT (1 << AMDGPU_RAS_BLOCK__UMC)
-#define DEFAULT_RAS_BLOCK_MASK_QUERY (1 << AMDGPU_RAS_BLOCK__UMC)
+#define DEFAULT_RAS_BLOCK_MASK_INJECT ((1 << AMDGPU_RAS_BLOCK__UMC) |\
+ (1 << AMDGPU_RAS_BLOCK__GFX))
+#define DEFAULT_RAS_BLOCK_MASK_QUERY ((1 << AMDGPU_RAS_BLOCK__UMC) |\
+ (1 << AMDGPU_RAS_BLOCK__GFX))
#define DEFAULT_RAS_BLOCK_MASK_BASIC (1 << AMDGPU_RAS_BLOCK__UMC |\
(1 << AMDGPU_RAS_BLOCK__SDMA) |\
(1 << AMDGPU_RAS_BLOCK__GFX))
@@ -146,12 +393,78 @@ struct ras_DID_test_mask{
DEFAULT_RAS_BLOCK_MASK_BASIC\
}
+static const struct ras_inject_test_config umc_ras_inject_test[] = {
+ {"ras_umc.1.0", "umc", 0, AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+};
+
+static const struct ras_inject_test_config gfx_ras_inject_test[] = {
+ {"ras_gfx.2.0", "gfx", AMDGPU_RAS_BLOCK__GFX_CPC_UCODE,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.1", "gfx", AMDGPU_RAS_BLOCK__GFX_CPF_TAG,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.2", "gfx", AMDGPU_RAS_BLOCK__GFX_CPG_TAG,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.3", "gfx", AMDGPU_RAS_BLOCK__GFX_SQ_LDS_D,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.4", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_DATA_CU1_UTCL1_LFIFO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.5", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKA_TAG_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.6", "gfx", AMDGPU_RAS_BLOCK__GFX_SQC_INST_BANKB_TAG_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.7", "gfx", AMDGPU_RAS_BLOCK__GFX_TA_FS_DFIFO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.8", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.9", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_0_1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.10", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_0,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.11", "gfx", AMDGPU_RAS_BLOCK__GFX_TCC_CACHE_DATA_BANK_1_1,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.12", "gfx", AMDGPU_RAS_BLOCK__GFX_TCP_CACHE_RAM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.13", "gfx", AMDGPU_RAS_BLOCK__GFX_TD_SS_FIFO_LO,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+ {"ras_gfx.2.14", "gfx", AMDGPU_RAS_BLOCK__GFX_EA_DRAMRD_CMDMEM,
+ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE, 0, 0},
+};
+
static const struct ras_DID_test_mask ras_DID_array[] = {
{0x66a1, 0x00, RAS_BLOCK_MASK_ALL},
{0x66a1, 0x01, RAS_BLOCK_MASK_ALL},
{0x66a1, 0x04, RAS_BLOCK_MASK_ALL},
};
+static uint32_t amdgpu_ras_find_block_id_by_name(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ras_block_string); i++) {
+ if (strcmp(name, ras_block_string[i]) == 0)
+ return i;
+ }
+
+ return ARRAY_SIZE(ras_block_string);
+}
+
+static char *amdgpu_ras_get_error_type_id(enum amdgpu_ras_error_type type)
+{
+ switch (type) {
+ case AMDGPU_RAS_ERROR__PARITY:
+ return "parity";
+ case AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE:
+ return "single_correctable";
+ case AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE:
+ return "multi_uncorrectable";
+ case AMDGPU_RAS_ERROR__POISON:
+ return "poison";
+ case AMDGPU_RAS_ERROR__NONE:
+ default:
+ return NULL;
+ }
+}
+
static struct ras_test_mask amdgpu_ras_get_test_mask(drmDevicePtr device)
{
int i;
@@ -188,7 +501,7 @@ static int get_file_contents(char *file, char *buf, int size);
static int amdgpu_ras_lookup_id(drmDevicePtr device)
{
- char path[1024];
+ char path[PATH_SIZE];
char str[128];
drmPciBusInfo info;
int i;
@@ -197,7 +510,7 @@ static int amdgpu_ras_lookup_id(drmDevicePtr device)
for (i = 0; i < MAX_CARDS_SUPPORTED; i++) {
memset(str, 0, sizeof(str));
memset(&info, 0, sizeof(info));
- sprintf(path, "/sys/kernel/debug/dri/%d/name", i);
+ snprintf(path, PATH_SIZE, "/sys/kernel/debug/dri/%d/name", i);
if (get_file_contents(path, str, sizeof(str)) <= 0)
continue;
@@ -212,146 +525,24 @@ static int amdgpu_ras_lookup_id(drmDevicePtr device)
return -1;
}
-CU_BOOL suite_ras_tests_enable(void)
-{
- amdgpu_device_handle device_handle;
- uint32_t major_version;
- uint32_t minor_version;
- int i;
- drmDevicePtr device;
-
- for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
- if (amdgpu_device_initialize(drm_amdgpu[i], &major_version,
- &minor_version, &device_handle))
- continue;
-
- if (drmGetDevice2(drm_amdgpu[i],
- DRM_DEVICE_GET_PCI_REVISION,
- &device))
- continue;
-
- if (device->bustype == DRM_BUS_PCI &&
- amdgpu_ras_lookup_capability(device_handle)) {
- amdgpu_device_deinitialize(device_handle);
- return CU_TRUE;
- }
-
- if (amdgpu_device_deinitialize(device_handle))
- continue;
- }
-
- return CU_FALSE;
-}
-
-int suite_ras_tests_init(void)
-{
- drmDevicePtr device;
- amdgpu_device_handle device_handle;
- uint32_t major_version;
- uint32_t minor_version;
- uint32_t capability;
- struct ras_test_mask test_mask;
- int id;
- int i;
- int r;
-
- for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
- r = amdgpu_device_initialize(drm_amdgpu[i], &major_version,
- &minor_version, &device_handle);
- if (r)
- continue;
-
- if (drmGetDevice2(drm_amdgpu[i],
- DRM_DEVICE_GET_PCI_REVISION,
- &device)) {
- amdgpu_device_deinitialize(device_handle);
- continue;
- }
-
- if (device->bustype != DRM_BUS_PCI) {
- amdgpu_device_deinitialize(device_handle);
- continue;
- }
-
- capability = amdgpu_ras_lookup_capability(device_handle);
- if (capability == 0) {
- amdgpu_device_deinitialize(device_handle);
- continue;
-
- }
-
- id = amdgpu_ras_lookup_id(device);
- if (id == -1) {
- amdgpu_device_deinitialize(device_handle);
- continue;
- }
-
- test_mask = amdgpu_ras_get_test_mask(device);
-
- devices[devices_count++] = (struct amdgpu_ras_data) {
- device_handle, id, capability, test_mask,
- };
- }
-
- if (devices_count == 0)
- return CUE_SINIT_FAILED;
-
- return CUE_SUCCESS;
-}
-
-int suite_ras_tests_clean(void)
-{
- int r;
- int i;
- int ret = CUE_SUCCESS;
-
- for (i = 0; i < devices_count; i++) {
- r = amdgpu_device_deinitialize(devices[i].device_handle);
- if (r)
- ret = CUE_SCLEAN_FAILED;
- }
- return ret;
-}
-
-static void amdgpu_ras_disable_test(void);
-static void amdgpu_ras_enable_test(void);
-static void amdgpu_ras_inject_test(void);
-static void amdgpu_ras_query_test(void);
-static void amdgpu_ras_basic_test(void);
-
-CU_TestInfo ras_tests[] = {
- { "ras basic test", amdgpu_ras_basic_test },
- { "ras query test", amdgpu_ras_query_test },
- { "ras inject test", amdgpu_ras_inject_test },
- { "ras disable test", amdgpu_ras_disable_test },
-#if 0
- { "ras enable test", amdgpu_ras_enable_test },
-#endif
- CU_TEST_INFO_NULL,
-};
-
//helpers
static int test_card;
-static char sysfs_path[1024];
-static char debugfs_path[1024];
+static char sysfs_path[PATH_SIZE];
+static char debugfs_path[PATH_SIZE];
static uint32_t ras_mask;
static amdgpu_device_handle device_handle;
-static int set_test_card(int card)
+static void set_test_card(int card)
{
- int i;
-
test_card = card;
- sprintf(sysfs_path, "/sys/class/drm/card%d/device/ras/", devices[card].id);
- sprintf(debugfs_path, "/sys/kernel/debug/dri/%d/ras/", devices[card].id);
+ snprintf(sysfs_path, PATH_SIZE, "/sys/class/drm/card%d/device/ras/", devices[card].id);
+ snprintf(debugfs_path, PATH_SIZE, "/sys/kernel/debug/dri/%d/ras/", devices[card].id);
ras_mask = devices[card].capability;
device_handle = devices[card].device_handle;
ras_block_mask_inject = devices[card].test_mask.inject_mask;
ras_block_mask_query = devices[card].test_mask.query_mask;
ras_block_mask_basic = devices[card].test_mask.basic_mask;
-
- return 0;
}
static const char *get_ras_sysfs_root(void)
@@ -417,10 +608,11 @@ static int amdgpu_ras_is_feature_supported(enum amdgpu_ras_block block)
static int amdgpu_ras_invoke(struct ras_debug_if *data)
{
- char path[1024];
+ char path[PATH_SIZE];
int ret;
- sprintf(path, "%s%s", get_ras_debugfs_root(), "ras_ctrl");
+ snprintf(path, sizeof(path), "%s", get_ras_debugfs_root());
+ strncat(path, "ras_ctrl", sizeof(path) - strlen(path));
ret = set_file_contents(path, (char *)data, sizeof(*data))
- sizeof(*data);
@@ -431,15 +623,16 @@ static int amdgpu_ras_query_err_count(enum amdgpu_ras_block block,
unsigned long *ue, unsigned long *ce)
{
char buf[64];
- char name[1024];
- int ret;
+ char name[PATH_SIZE];
*ue = *ce = 0;
if (amdgpu_ras_is_feature_supported(block) <= 0)
return -1;
- sprintf(name, "%s%s%s", get_ras_sysfs_root(), ras_block_str(block), "_err_count");
+ snprintf(name, sizeof(name), "%s", get_ras_sysfs_root());
+ strncat(name, ras_block_str(block), sizeof(name) - strlen(name));
+ strncat(name, "_err_count", sizeof(name) - strlen(name));
if (is_file_ok(name, O_RDONLY))
return 0;
@@ -453,6 +646,34 @@ static int amdgpu_ras_query_err_count(enum amdgpu_ras_block block,
return 0;
}
+static int amdgpu_ras_inject(enum amdgpu_ras_block block,
+ uint32_t sub_block, enum amdgpu_ras_error_type type,
+ uint64_t address, uint64_t value)
+{
+ struct ras_debug_if data = { .op = 2, };
+ struct ras_inject_if *inject = &data.inject;
+ int ret;
+
+ if (amdgpu_ras_is_feature_enabled(block) <= 0) {
+ fprintf(stderr, "block id(%d) is not valid\n", block);
+ return -1;
+ }
+
+ inject->head.block = block;
+ inject->head.type = type;
+ inject->head.sub_block_index = sub_block;
+ strncpy(inject->head.name, ras_block_str(block), sizeof(inject->head.name)-1);
+ inject->address = address;
+ inject->value = value;
+
+ ret = amdgpu_ras_invoke(&data);
+ CU_ASSERT_EQUAL(ret, 0);
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
//tests
static void amdgpu_ras_features_test(int enable)
{
@@ -503,69 +724,83 @@ static void amdgpu_ras_enable_test(void)
}
}
-static void __amdgpu_ras_inject_test(void)
+static void __amdgpu_ras_ip_inject_test(const struct ras_inject_test_config *ip_test,
+ uint32_t size)
{
- struct ras_debug_if data;
- int ret;
- int i;
- unsigned long ue, ce, ue_old, ce_old;
+ int i, ret;
+ unsigned long old_ue, old_ce;
+ unsigned long ue, ce;
+ uint32_t block;
+ int timeout;
+ bool pass;
- data.op = 2;
- for (i = 0; i < AMDGPU_RAS_BLOCK__LAST; i++) {
- int timeout = 3;
- struct ras_inject_if inject = {
- .head = {
- .block = i,
- .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
- .sub_block_index = 0,
- .name = "",
- },
- .address = 0,
- .value = 0,
- };
+ for (i = 0; i < size; i++) {
+ timeout = 3;
+ pass = false;
- if (amdgpu_ras_is_feature_enabled(i) <= 0)
- continue;
+ block = amdgpu_ras_find_block_id_by_name(ip_test[i].block);
- if (!((1 << i) & ras_block_mask_inject))
- continue;
+ /* Ensure one valid ip block */
+ if (block == ARRAY_SIZE(ras_block_string))
+ break;
- data.inject = inject;
+ /* Ensure RAS feature for the IP block is enabled by kernel */
+ if (amdgpu_ras_is_feature_supported(block) <= 0)
+ break;
- ret = amdgpu_ras_query_err_count(i, &ue_old, &ce_old);
+ ret = amdgpu_ras_query_err_count(block, &old_ue, &old_ce);
CU_ASSERT_EQUAL(ret, 0);
-
if (ret)
- continue;
+ break;
- ret = amdgpu_ras_invoke(&data);
+ ret = amdgpu_ras_inject(block,
+ ip_test[i].sub_block,
+ ip_test[i].type,
+ ip_test[i].address,
+ ip_test[i].value);
CU_ASSERT_EQUAL(ret, 0);
-
if (ret)
- continue;
+ break;
-loop:
while (timeout > 0) {
- ret = amdgpu_ras_query_err_count(i, &ue, &ce);
- CU_ASSERT_EQUAL(ret, 0);
+ sleep(5);
+ ret = amdgpu_ras_query_err_count(block, &ue, &ce);
+ CU_ASSERT_EQUAL(ret, 0);
if (ret)
- continue;
- if (ue_old != ue) {
- /*recovery takes ~10s*/
- sleep(10);
break;
- }
- sleep(1);
+ if (old_ue != ue || old_ce != ce) {
+ pass = true;
+ sleep(20);
+ break;
+ }
timeout -= 1;
}
-
- CU_ASSERT_EQUAL(ue_old + 1, ue);
- CU_ASSERT_EQUAL(ce_old, ce);
+ printf("\t Test %s@block %s, subblock %d, error_type %s, address %ld, value %ld: %s\n",
+ ip_test[i].name,
+ ip_test[i].block,
+ ip_test[i].sub_block,
+ amdgpu_ras_get_error_type_id(ip_test[i].type),
+ ip_test[i].address,
+ ip_test[i].value,
+ pass ? "Pass" : "Fail");
}
}
+static void __amdgpu_ras_inject_test(void)
+{
+ printf("...\n");
+
+ /* run UMC ras inject test */
+ __amdgpu_ras_ip_inject_test(umc_ras_inject_test,
+ ARRAY_SIZE(umc_ras_inject_test));
+
+ /* run GFX ras inject test */
+ __amdgpu_ras_ip_inject_test(gfx_ras_inject_test,
+ ARRAY_SIZE(gfx_ras_inject_test));
+}
+
static void amdgpu_ras_inject_test(void)
{
int i;
@@ -604,13 +839,11 @@ static void amdgpu_ras_query_test(void)
static void amdgpu_ras_basic_test(void)
{
- unsigned long ue, ce;
- char name[1024];
int ret;
int i;
int j;
uint32_t features;
- char path[1024];
+ char path[PATH_SIZE];
ret = is_file_ok("/sys/module/amdgpu/parameters/ras_mask", O_RDONLY);
CU_ASSERT_EQUAL(ret, 0);
@@ -622,11 +855,15 @@ static void amdgpu_ras_basic_test(void)
sizeof(features), &features);
CU_ASSERT_EQUAL(ret, 0);
- sprintf(path, "%s%s", get_ras_debugfs_root(), "ras_ctrl");
+ snprintf(path, sizeof(path), "%s", get_ras_debugfs_root());
+ strncat(path, "ras_ctrl", sizeof(path) - strlen(path));
+
ret = is_file_ok(path, O_WRONLY);
CU_ASSERT_EQUAL(ret, 0);
- sprintf(path, "%s%s", get_ras_sysfs_root(), "features");
+ snprintf(path, sizeof(path), "%s", get_ras_sysfs_root());
+ strncat(path, "features", sizeof(path) - strlen(path));
+
ret = is_file_ok(path, O_RDONLY);
CU_ASSERT_EQUAL(ret, 0);
@@ -638,13 +875,129 @@ static void amdgpu_ras_basic_test(void)
if (!((1 << j) & ras_block_mask_basic))
continue;
- sprintf(path, "%s%s%s", get_ras_sysfs_root(), ras_block_str(j), "_err_count");
+ snprintf(path, sizeof(path), "%s", get_ras_sysfs_root());
+ strncat(path, ras_block_str(j), sizeof(path) - strlen(path));
+ strncat(path, "_err_count", sizeof(path) - strlen(path));
+
ret = is_file_ok(path, O_RDONLY);
CU_ASSERT_EQUAL(ret, 0);
- sprintf(path, "%s%s%s", get_ras_debugfs_root(), ras_block_str(j), "_err_inject");
+ snprintf(path, sizeof(path), "%s", get_ras_debugfs_root());
+ strncat(path, ras_block_str(j), sizeof(path) - strlen(path));
+ strncat(path, "_err_inject", sizeof(path) - strlen(path));
+
ret = is_file_ok(path, O_WRONLY);
CU_ASSERT_EQUAL(ret, 0);
}
}
}
+
+CU_TestInfo ras_tests[] = {
+ { "ras basic test", amdgpu_ras_basic_test },
+ { "ras query test", amdgpu_ras_query_test },
+ { "ras inject test", amdgpu_ras_inject_test },
+ { "ras disable test", amdgpu_ras_disable_test },
+ { "ras enable test", amdgpu_ras_enable_test },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_ras_tests_enable(void)
+{
+ amdgpu_device_handle device_handle;
+ uint32_t major_version;
+ uint32_t minor_version;
+ int i;
+ drmDevicePtr device;
+
+ for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
+ if (amdgpu_device_initialize(drm_amdgpu[i], &major_version,
+ &minor_version, &device_handle))
+ continue;
+
+ if (drmGetDevice2(drm_amdgpu[i],
+ DRM_DEVICE_GET_PCI_REVISION,
+ &device))
+ continue;
+
+ if (device->bustype == DRM_BUS_PCI &&
+ amdgpu_ras_lookup_capability(device_handle)) {
+ amdgpu_device_deinitialize(device_handle);
+ return CU_TRUE;
+ }
+
+ if (amdgpu_device_deinitialize(device_handle))
+ continue;
+ }
+
+ return CU_FALSE;
+}
+
+int suite_ras_tests_init(void)
+{
+ drmDevicePtr device;
+ amdgpu_device_handle device_handle;
+ uint32_t major_version;
+ uint32_t minor_version;
+ uint32_t capability;
+ struct ras_test_mask test_mask;
+ int id;
+ int i;
+ int r;
+
+ for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >= 0; i++) {
+ r = amdgpu_device_initialize(drm_amdgpu[i], &major_version,
+ &minor_version, &device_handle);
+ if (r)
+ continue;
+
+ if (drmGetDevice2(drm_amdgpu[i],
+ DRM_DEVICE_GET_PCI_REVISION,
+ &device)) {
+ amdgpu_device_deinitialize(device_handle);
+ continue;
+ }
+
+ if (device->bustype != DRM_BUS_PCI) {
+ amdgpu_device_deinitialize(device_handle);
+ continue;
+ }
+
+ capability = amdgpu_ras_lookup_capability(device_handle);
+ if (capability == 0) {
+ amdgpu_device_deinitialize(device_handle);
+ continue;
+
+ }
+
+ id = amdgpu_ras_lookup_id(device);
+ if (id == -1) {
+ amdgpu_device_deinitialize(device_handle);
+ continue;
+ }
+
+ test_mask = amdgpu_ras_get_test_mask(device);
+
+ devices[devices_count++] = (struct amdgpu_ras_data) {
+ device_handle, id, capability, test_mask,
+ };
+ }
+
+ if (devices_count == 0)
+ return CUE_SINIT_FAILED;
+
+ return CUE_SUCCESS;
+}
+
+int suite_ras_tests_clean(void)
+{
+ int r;
+ int i;
+ int ret = CUE_SUCCESS;
+
+ for (i = 0; i < devices_count; i++) {
+ r = amdgpu_device_deinitialize(devices[i].device_handle);
+ if (r)
+ ret = CUE_SCLEAN_FAILED;
+ }
+ return ret;
+}
diff --git a/tests/amdgpu/security_tests.c b/tests/amdgpu/security_tests.c
new file mode 100644
index 00000000..eed695a3
--- /dev/null
+++ b/tests/amdgpu/security_tests.c
@@ -0,0 +1,485 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * 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 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 HOLDER(S) OR AUTHOR(S) 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 "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+
+#include <string.h>
+#include <unistd.h>
+#ifdef __FreeBSD__
+#include <sys/endian.h>
+#else
+#include <endian.h>
+#endif
+#include <strings.h>
+#include <xf86drm.h>
+
+static amdgpu_device_handle device_handle;
+static uint32_t major_version;
+static uint32_t minor_version;
+
+static struct drm_amdgpu_info_hw_ip sdma_info;
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(_Arr) (sizeof(_Arr)/sizeof((_Arr)[0]))
+#endif
+
+
+/* --------------------- Secure bounce test ------------------------ *
+ *
+ * The secure bounce test tests that we can evict a TMZ buffer,
+ * and page it back in, via a bounce buffer, as it encryption/decryption
+ * depends on its physical address, and have the same data, i.e. data
+ * integrity is preserved.
+ *
+ * The steps are as follows (from Christian K.):
+ *
+ * Buffer A which is TMZ protected and filled by the CPU with a
+ * certain pattern. That the GPU is reading only random nonsense from
+ * that pattern is irrelevant for the test.
+ *
+ * This buffer A is then secure copied into buffer B which is also
+ * TMZ protected.
+ *
+ * Buffer B is moved around, from VRAM to GTT, GTT to SYSTEM,
+ * etc.
+ *
+ * Then, we use another secure copy of buffer B back to buffer A.
+ *
+ * And lastly we check with the CPU the pattern.
+ *
+ * Assuming that we don't have memory contention and buffer A stayed
+ * at the same place, we should still see the same pattern when read
+ * by the CPU.
+ *
+ * If we don't see the same pattern then something in the buffer
+ * migration code is not working as expected.
+ */
+
+#define SECURE_BOUNCE_TEST_STR "secure bounce"
+#define SECURE_BOUNCE_FAILED_STR SECURE_BOUNCE_TEST_STR " failed"
+
+#define PRINT_ERROR(_Res) fprintf(stderr, "%s:%d: %s (%d)\n", \
+ __func__, __LINE__, strerror(-(_Res)), _Res)
+
+#define PACKET_LCOPY_SIZE 7
+#define PACKET_NOP_SIZE 12
+
+struct sec_amdgpu_bo {
+ struct amdgpu_bo *bo;
+ struct amdgpu_va *va;
+};
+
+struct command_ctx {
+ struct amdgpu_device *dev;
+ struct amdgpu_cs_ib_info cs_ibinfo;
+ struct amdgpu_cs_request cs_req;
+ struct amdgpu_context *context;
+ int ring_id;
+};
+
+/**
+ * amdgpu_bo_alloc_map -- Allocate and map a buffer object (BO)
+ * @dev: The AMDGPU device this BO belongs to.
+ * @size: The size of the BO.
+ * @alignment: Alignment of the BO.
+ * @gem_domain: One of AMDGPU_GEM_DOMAIN_xyz.
+ * @alloc_flags: One of AMDGPU_GEM_CREATE_xyz.
+ * @sbo: the result
+ *
+ * Allocate a buffer object (BO) with the desired attributes
+ * as specified by the argument list and write out the result
+ * into @sbo.
+ *
+ * Return 0 on success and @sbo->bo and @sbo->va are set,
+ * or -errno on error.
+ */
+static int amdgpu_bo_alloc_map(struct amdgpu_device *dev,
+ unsigned size,
+ unsigned alignment,
+ unsigned gem_domain,
+ uint64_t alloc_flags,
+ struct sec_amdgpu_bo *sbo)
+{
+ void *cpu;
+ uint64_t mc_addr;
+
+ return amdgpu_bo_alloc_and_map_raw(dev,
+ size,
+ alignment,
+ gem_domain,
+ alloc_flags,
+ 0,
+ &sbo->bo,
+ &cpu, &mc_addr,
+ &sbo->va);
+}
+
+static void amdgpu_bo_unmap_free(struct sec_amdgpu_bo *sbo,
+ const uint64_t size)
+{
+ (void) amdgpu_bo_unmap_and_free(sbo->bo,
+ sbo->va,
+ sbo->va->address,
+ size);
+ sbo->bo = NULL;
+ sbo->va = NULL;
+}
+
+static void amdgpu_sdma_lcopy(uint32_t *packet,
+ const uint64_t dst,
+ const uint64_t src,
+ const uint32_t size,
+ const int secure)
+{
+ /* Set the packet to Linear copy with TMZ set.
+ */
+ packet[0] = htole32(secure << 18 | 1);
+ packet[1] = htole32(size-1);
+ packet[2] = htole32(0);
+ packet[3] = htole32((uint32_t)(src & 0xFFFFFFFFU));
+ packet[4] = htole32((uint32_t)(src >> 32));
+ packet[5] = htole32((uint32_t)(dst & 0xFFFFFFFFU));
+ packet[6] = htole32((uint32_t)(dst >> 32));
+}
+
+static void amdgpu_sdma_nop(uint32_t *packet, uint32_t nop_count)
+{
+ /* A packet of the desired number of NOPs.
+ */
+ packet[0] = htole32(nop_count << 16);
+ for ( ; nop_count > 0; nop_count--)
+ packet[nop_count-1] = 0;
+}
+
+/**
+ * amdgpu_bo_lcopy -- linear copy with TMZ set, using sDMA
+ * @dev: AMDGPU device to which both buffer objects belong to
+ * @dst: destination buffer object
+ * @src: source buffer object
+ * @size: size of memory to move, in bytes.
+ * @secure: Set to 1 to perform secure copy, 0 for clear
+ *
+ * Issues and waits for completion of a Linear Copy with TMZ
+ * set, to the sDMA engine. @size should be a multiple of
+ * at least 16 bytes.
+ */
+static void amdgpu_bo_lcopy(struct command_ctx *ctx,
+ struct sec_amdgpu_bo *dst,
+ struct sec_amdgpu_bo *src,
+ const uint32_t size,
+ int secure)
+{
+ struct amdgpu_bo *bos[] = { dst->bo, src->bo };
+ uint32_t packet[PACKET_LCOPY_SIZE];
+
+ amdgpu_sdma_lcopy(packet,
+ dst->va->address,
+ src->va->address,
+ size, secure);
+ amdgpu_test_exec_cs_helper_raw(ctx->dev, ctx->context,
+ AMDGPU_HW_IP_DMA, ctx->ring_id,
+ ARRAY_SIZE(packet), packet,
+ ARRAY_SIZE(bos), bos,
+ &ctx->cs_ibinfo, &ctx->cs_req,
+ secure == 1);
+}
+
+/**
+ * amdgpu_bo_move -- Evoke a move of the buffer object (BO)
+ * @dev: device to which this buffer object belongs to
+ * @bo: the buffer object to be moved
+ * @whereto: one of AMDGPU_GEM_DOMAIN_xyz
+ * @secure: set to 1 to submit secure IBs
+ *
+ * Evokes a move of the buffer object @bo to the GEM domain
+ * descibed by @whereto.
+ *
+ * Returns 0 on sucess; -errno on error.
+ */
+static int amdgpu_bo_move(struct command_ctx *ctx,
+ struct amdgpu_bo *bo,
+ uint64_t whereto,
+ int secure)
+{
+ struct amdgpu_bo *bos[] = { bo };
+ struct drm_amdgpu_gem_op gop = {
+ .handle = bo->handle,
+ .op = AMDGPU_GEM_OP_SET_PLACEMENT,
+ .value = whereto,
+ };
+ uint32_t packet[PACKET_NOP_SIZE];
+ int res;
+
+ /* Change the buffer's placement.
+ */
+ res = drmIoctl(ctx->dev->fd, DRM_IOCTL_AMDGPU_GEM_OP, &gop);
+ if (res)
+ return -errno;
+
+ /* Now issue a NOP to actually evoke the MM to move
+ * it to the desired location.
+ */
+ amdgpu_sdma_nop(packet, PACKET_NOP_SIZE);
+ amdgpu_test_exec_cs_helper_raw(ctx->dev, ctx->context,
+ AMDGPU_HW_IP_DMA, ctx->ring_id,
+ ARRAY_SIZE(packet), packet,
+ ARRAY_SIZE(bos), bos,
+ &ctx->cs_ibinfo, &ctx->cs_req,
+ secure == 1);
+ return 0;
+}
+
+/* Safe, O Sec!
+ */
+static const uint8_t secure_pattern[] = { 0x5A, 0xFE, 0x05, 0xEC };
+
+#define SECURE_BUFFER_SIZE (4 * 1024 * sizeof(secure_pattern))
+
+static void amdgpu_secure_bounce(void)
+{
+ struct sec_amdgpu_bo alice, bob;
+ struct command_ctx sb_ctx;
+ long page_size;
+ uint8_t *pp;
+ int res;
+
+ page_size = sysconf(_SC_PAGESIZE);
+
+ memset(&sb_ctx, 0, sizeof(sb_ctx));
+ sb_ctx.dev = device_handle;
+ res = amdgpu_cs_ctx_create(sb_ctx.dev, &sb_ctx.context);
+ if (res) {
+ PRINT_ERROR(res);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ return;
+ }
+
+ /* Use the first present ring.
+ */
+ res = ffs(sdma_info.available_rings) - 1;
+ if (res == -1) {
+ PRINT_ERROR(-ENOENT);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ goto Out_free_ctx;
+ }
+ sb_ctx.ring_id = res;
+
+ /* Allocate a buffer named Alice in VRAM.
+ */
+ res = amdgpu_bo_alloc_map(device_handle,
+ SECURE_BUFFER_SIZE,
+ page_size,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_ENCRYPTED,
+ &alice);
+ if (res) {
+ PRINT_ERROR(res);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ return;
+ }
+
+ /* Fill Alice with a pattern.
+ */
+ for (pp = alice.bo->cpu_ptr;
+ pp < (typeof(pp)) alice.bo->cpu_ptr + SECURE_BUFFER_SIZE;
+ pp += sizeof(secure_pattern))
+ memcpy(pp, secure_pattern, sizeof(secure_pattern));
+
+ /* Allocate a buffer named Bob in VRAM.
+ */
+ res = amdgpu_bo_alloc_map(device_handle,
+ SECURE_BUFFER_SIZE,
+ page_size,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ 0 /* AMDGPU_GEM_CREATE_ENCRYPTED */,
+ &bob);
+ if (res) {
+ PRINT_ERROR(res);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ goto Out_free_Alice;
+ }
+
+ /* sDMA clear copy from Alice to Bob.
+ */
+ amdgpu_bo_lcopy(&sb_ctx, &bob, &alice, SECURE_BUFFER_SIZE, 0);
+
+ /* Move Bob to the GTT domain.
+ */
+ res = amdgpu_bo_move(&sb_ctx, bob.bo, AMDGPU_GEM_DOMAIN_GTT, 0);
+ if (res) {
+ PRINT_ERROR(res);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ goto Out_free_all;
+ }
+
+ /* sDMA clear copy from Bob to Alice.
+ */
+ amdgpu_bo_lcopy(&sb_ctx, &alice, &bob, SECURE_BUFFER_SIZE, 0);
+
+ /* Verify the contents of Alice.
+ */
+ for (pp = alice.bo->cpu_ptr;
+ pp < (typeof(pp)) alice.bo->cpu_ptr + SECURE_BUFFER_SIZE;
+ pp += sizeof(secure_pattern)) {
+ res = memcmp(pp, secure_pattern, sizeof(secure_pattern));
+ if (res) {
+ fprintf(stderr, SECURE_BOUNCE_FAILED_STR);
+ CU_FAIL(SECURE_BOUNCE_FAILED_STR);
+ break;
+ }
+ }
+
+Out_free_all:
+ amdgpu_bo_unmap_free(&bob, SECURE_BUFFER_SIZE);
+Out_free_Alice:
+ amdgpu_bo_unmap_free(&alice, SECURE_BUFFER_SIZE);
+Out_free_ctx:
+ res = amdgpu_cs_ctx_free(sb_ctx.context);
+ CU_ASSERT_EQUAL(res, 0);
+}
+
+/* ----------------------------------------------------------------- */
+
+static void amdgpu_security_alloc_buf_test(void)
+{
+ amdgpu_bo_handle bo;
+ amdgpu_va_handle va_handle;
+ uint64_t bo_mc;
+ int r;
+
+ /* Test secure buffer allocation in VRAM */
+ bo = gpu_mem_alloc(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_CREATE_ENCRYPTED,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test secure buffer allocation in system memory */
+ bo = gpu_mem_alloc(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_CREATE_ENCRYPTED,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+
+ /* Test secure buffer allocation in invisible VRAM */
+ bo = gpu_mem_alloc(device_handle, 4096, 4096,
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_CREATE_ENCRYPTED |
+ AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
+ &bo_mc, &va_handle);
+
+ r = gpu_mem_free(bo, va_handle, bo_mc, 4096);
+ CU_ASSERT_EQUAL(r, 0);
+}
+
+static void amdgpu_security_gfx_submission_test(void)
+{
+ amdgpu_command_submission_write_linear_helper_with_secure(device_handle,
+ AMDGPU_HW_IP_GFX,
+ true);
+}
+
+static void amdgpu_security_sdma_submission_test(void)
+{
+ amdgpu_command_submission_write_linear_helper_with_secure(device_handle,
+ AMDGPU_HW_IP_DMA,
+ true);
+}
+
+/* ----------------------------------------------------------------- */
+
+CU_TestInfo security_tests[] = {
+ { "allocate secure buffer test", amdgpu_security_alloc_buf_test },
+ { "graphics secure command submission", amdgpu_security_gfx_submission_test },
+ { "sDMA secure command submission", amdgpu_security_sdma_submission_test },
+ { SECURE_BOUNCE_TEST_STR, amdgpu_secure_bounce },
+ CU_TEST_INFO_NULL,
+};
+
+CU_BOOL suite_security_tests_enable(void)
+{
+ CU_BOOL enable = CU_TRUE;
+
+ if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle))
+ return CU_FALSE;
+
+ if (device_handle->info.family_id != AMDGPU_FAMILY_RV) {
+ printf("\n\nDon't support TMZ (trust memory zone), security suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if ((major_version < 3) ||
+ ((major_version == 3) && (minor_version < 37))) {
+ printf("\n\nDon't support TMZ (trust memory zone), kernel DRM version (%d.%d)\n",
+ major_version, minor_version);
+ printf("is older, security suite disabled\n");
+ enable = CU_FALSE;
+ }
+
+ if (amdgpu_device_deinitialize(device_handle))
+ return CU_FALSE;
+
+ return enable;
+}
+
+int suite_security_tests_init(void)
+{
+ int res;
+
+ res = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
+ &minor_version, &device_handle);
+ if (res) {
+ PRINT_ERROR(res);
+ return CUE_SINIT_FAILED;
+ }
+
+ res = amdgpu_query_hw_ip_info(device_handle,
+ AMDGPU_HW_IP_DMA,
+ 0, &sdma_info);
+ if (res) {
+ PRINT_ERROR(res);
+ return CUE_SINIT_FAILED;
+ }
+
+ return CUE_SUCCESS;
+}
+
+int suite_security_tests_clean(void)
+{
+ int res;
+
+ res = amdgpu_device_deinitialize(device_handle);
+ if (res)
+ return CUE_SCLEAN_FAILED;
+
+ return CUE_SUCCESS;
+}
diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
index 869ed88e..3a7b38eb 100644
--- a/tests/amdgpu/syncobj_tests.c
+++ b/tests/amdgpu/syncobj_tests.c
@@ -96,7 +96,7 @@ static int syncobj_command_submission_helper(uint32_t syncobj_handle, bool
struct amdgpu_cs_fence fence_status;
amdgpu_bo_list_handle bo_list;
amdgpu_va_handle va_handle;
- uint32_t expired, flags;
+ uint32_t expired;
int i, r;
uint64_t seq_no;
static uint32_t *ptr;
diff --git a/tests/amdgpu/vce_tests.c b/tests/amdgpu/vce_tests.c
index 0026826e..5434e444 100644
--- a/tests/amdgpu/vce_tests.c
+++ b/tests/amdgpu/vce_tests.c
@@ -96,7 +96,7 @@ CU_TestInfo vce_tests[] = {
CU_BOOL suite_vce_tests_enable(void)
{
- uint32_t version, feature;
+ uint32_t version, feature, asic_id;
CU_BOOL ret_mv = CU_FALSE;
if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
@@ -107,6 +107,7 @@ CU_BOOL suite_vce_tests_enable(void)
chip_rev = device_handle->info.chip_rev;
chip_id = device_handle->info.chip_external_rev;
ids_flags = device_handle->info.ids_flags;
+ asic_id = device_handle->info.asic_id;
amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0,
0, &version, &feature);
@@ -114,7 +115,8 @@ CU_BOOL suite_vce_tests_enable(void)
if (amdgpu_device_deinitialize(device_handle))
return CU_FALSE;
- if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI) {
+ if (family_id >= AMDGPU_FAMILY_RV || family_id == AMDGPU_FAMILY_SI ||
+ asic_is_arcturus(asic_id)) {
printf("\n\nThe ASIC NOT support VCE, suite disabled\n");
return CU_FALSE;
}
diff --git a/tests/amdgpu/vcn_tests.c b/tests/amdgpu/vcn_tests.c
index ad438f35..1ca66297 100644
--- a/tests/amdgpu/vcn_tests.c
+++ b/tests/amdgpu/vcn_tests.c
@@ -56,6 +56,11 @@ static amdgpu_device_handle device_handle;
static uint32_t major_version;
static uint32_t minor_version;
static uint32_t family_id;
+static uint32_t chip_rev;
+static uint32_t chip_id;
+static uint32_t asic_id;
+static uint32_t chip_rev;
+static uint32_t chip_id;
static amdgpu_context_handle context_handle;
static amdgpu_bo_handle ib_handle;
@@ -89,34 +94,74 @@ CU_TestInfo vcn_tests[] = {
CU_BOOL suite_vcn_tests_enable(void)
{
+ struct drm_amdgpu_info_hw_ip info;
+ int r;
if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
&minor_version, &device_handle))
return CU_FALSE;
family_id = device_handle->info.family_id;
+ asic_id = device_handle->info.asic_id;
+ chip_rev = device_handle->info.chip_rev;
+ chip_id = device_handle->info.chip_external_rev;
+
+ r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_DEC, 0, &info);
if (amdgpu_device_deinitialize(device_handle))
return CU_FALSE;
-
- if (family_id < AMDGPU_FAMILY_RV) {
+ if (r != 0 || !info.available_rings ||
+ (family_id < AMDGPU_FAMILY_RV &&
+ (family_id == AMDGPU_FAMILY_AI &&
+ chip_id != (chip_rev + 0x32)))) { /* Arcturus */
printf("\n\nThe ASIC NOT support VCN, suite disabled\n");
return CU_FALSE;
}
+ if (family_id == AMDGPU_FAMILY_AI) {
+ amdgpu_set_test_active("VCN Tests", "VCN ENC create", CU_FALSE);
+ amdgpu_set_test_active("VCN Tests", "VCN ENC decode", CU_FALSE);
+ amdgpu_set_test_active("VCN Tests", "VCN ENC destroy", CU_FALSE);
+ }
+
if (family_id == AMDGPU_FAMILY_RV) {
- reg.data0 = 0x81c4;
- reg.data1 = 0x81c5;
- reg.cmd = 0x81c3;
- reg.nop = 0x81ff;
- reg.cntl = 0x81c6;
+ if (chip_id >= (chip_rev + 0x91)) {
+ reg.data0 = 0x504;
+ reg.data1 = 0x505;
+ reg.cmd = 0x503;
+ reg.nop = 0x53f;
+ reg.cntl = 0x506;
+ } else {
+ reg.data0 = 0x81c4;
+ reg.data1 = 0x81c5;
+ reg.cmd = 0x81c3;
+ reg.nop = 0x81ff;
+ reg.cntl = 0x81c6;
+ }
} else if (family_id == AMDGPU_FAMILY_NV) {
- reg.data0 = 0x504;
- reg.data1 = 0x505;
- reg.cmd = 0x503;
- reg.nop = 0x53f;
- reg.cntl = 0x506;
+ if (chip_id == (chip_rev + 0x28) ||
+ chip_id == (chip_rev + 0x32) ||
+ chip_id == (chip_rev + 0x3c)) {
+ reg.data0 = 0x10;
+ reg.data1 = 0x11;
+ reg.cmd = 0xf;
+ reg.nop = 0x29;
+ reg.cntl = 0x26d;
+ }
+ else {
+ reg.data0 = 0x504;
+ reg.data1 = 0x505;
+ reg.cmd = 0x503;
+ reg.nop = 0x53f;
+ reg.cntl = 0x506;
+ }
+ } else if (family_id == AMDGPU_FAMILY_AI) {
+ reg.data0 = 0x10;
+ reg.data1 = 0x11;
+ reg.cmd = 0xf;
+ reg.nop = 0x29;
+ reg.cntl = 0x26d;
} else
return CU_FALSE;
@@ -333,6 +378,7 @@ static void amdgpu_cs_vcn_dec_decode(void)
avc_decode_msg, sizeof(avc_decode_msg));
dec += 4*1024;
+ memcpy(dec, feedback_msg, sizeof(feedback_msg));
dec += 4*1024;
memcpy(dec, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
diff --git a/tests/amdgpu/vm_tests.c b/tests/amdgpu/vm_tests.c
index 69bc4683..95011ea0 100644
--- a/tests/amdgpu/vm_tests.c
+++ b/tests/amdgpu/vm_tests.c
@@ -104,6 +104,14 @@ static void amdgpu_vmid_reserve_test(void)
amdgpu_bo_list_handle bo_list;
amdgpu_va_handle va_handle;
static uint32_t *ptr;
+ struct amdgpu_gpu_info gpu_info = {0};
+ unsigned gc_ip_type;
+
+ r = amdgpu_query_gpu_info(device_handle, &gpu_info);
+ CU_ASSERT_EQUAL(r, 0);
+
+ gc_ip_type = (asic_is_arcturus(gpu_info.asic_id)) ?
+ AMDGPU_HW_IP_COMPUTE : AMDGPU_HW_IP_GFX;
r = amdgpu_cs_ctx_create(device_handle, &context_handle);
CU_ASSERT_EQUAL(r, 0);
@@ -133,7 +141,7 @@ static void amdgpu_vmid_reserve_test(void)
ib_info.size = 16;
memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request));
- ibs_request.ip_type = AMDGPU_HW_IP_GFX;
+ ibs_request.ip_type = gc_ip_type;
ibs_request.ring = 0;
ibs_request.number_of_ibs = 1;
ibs_request.ibs = &ib_info;
@@ -146,7 +154,7 @@ static void amdgpu_vmid_reserve_test(void)
memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence));
fence_status.context = context_handle;
- fence_status.ip_type = AMDGPU_HW_IP_GFX;
+ fence_status.ip_type = gc_ip_type;
fence_status.ip_instance = 0;
fence_status.ring = 0;
fence_status.fence = ibs_request.seq_no;
diff --git a/tests/etnaviv/Makefile.am b/tests/etnaviv/Makefile.am
deleted file mode 100644
index 3e0c6120..00000000
--- a/tests/etnaviv/Makefile.am
+++ /dev/null
@@ -1,43 +0,0 @@
-AM_CFLAGS = \
- -fvisibility=hidden \
- -I $(top_srcdir)/include/drm \
- -I $(top_srcdir)/etnaviv \
- -I $(top_srcdir)
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- etnaviv_2d_test \
- etnaviv_cmd_stream_test \
- etnaviv_bo_cache_test
-else
-noinst_PROGRAMS = \
- etnaviv_2d_test \
- etnaviv_cmd_stream_test \
- etnaviv_bo_cache_test
-endif
-
-etnaviv_2d_test_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/etnaviv/libdrm_etnaviv.la
-
-etnaviv_2d_test_SOURCES = \
- cmdstream.xml.h \
- etnaviv_2d_test.c \
- state.xml.h \
- state_2d.xml.h \
- write_bmp.c \
- write_bmp.h
-
-etnaviv_cmd_stream_test_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/etnaviv/libdrm_etnaviv.la
-
-etnaviv_cmd_stream_test_SOURCES = \
- etnaviv_cmd_stream_test.c
-
-etnaviv_bo_cache_test_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/etnaviv/libdrm_etnaviv.la
-
-etnaviv_bo_cache_test_SOURCES = \
- etnaviv_bo_cache_test.c
diff --git a/tests/etnaviv/etnaviv_2d_test.c b/tests/etnaviv/etnaviv_2d_test.c
index 8dd77b66..e774ce9c 100644
--- a/tests/etnaviv/etnaviv_2d_test.c
+++ b/tests/etnaviv/etnaviv_2d_test.c
@@ -31,7 +31,7 @@
#include "xf86drm.h"
#include "etnaviv_drmif.h"
-#include "etnaviv_drm.h"
+#include <drm/etnaviv_drm.h>
#include "state.xml.h"
#include "state_2d.xml.h"
@@ -147,6 +147,27 @@ static void gen_cmd_stream(struct etna_cmd_stream *stream, struct etna_bo *bmp,
etna_set_state(stream, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_PE2D);
}
+int etna_check_image(uint32_t *p, int width, int height)
+{
+ int i;
+ uint32_t expected;
+
+ for (i = 0; i < width * height; i++) {
+ if (i%8 < 4 && i%(width*8) < width*4 && i%width < 8*16 && i < width*8*16)
+ expected = 0xff40ff40;
+ else
+ expected = 0x00000000;
+
+ if (p[i] != expected) {
+ fprintf(stderr, "Offset %d: expected: 0x%08x, got: 0x%08x\n",
+ i, expected, p[i]);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
const int width = 256;
@@ -161,10 +182,19 @@ int main(int argc, char *argv[])
drmVersionPtr version;
int fd, ret = 0;
+ uint64_t feat;
+ int core = 0;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s /dev/dri/<device> [<etna.bmp>]\n", argv[0]);
+ return 1;
+ }
fd = open(argv[1], O_RDWR);
- if (fd < 0)
+ if (fd < 0) {
+ perror(argv[1]);
return 1;
+ }
version = drmGetVersion(fd);
if (version) {
@@ -178,25 +208,44 @@ int main(int argc, char *argv[])
dev = etna_device_new(fd);
if (!dev) {
+ perror("etna_device_new");
ret = 2;
goto out;
}
- /* TODO: we assume that core 0 is a 2D capable one */
- gpu = etna_gpu_new(dev, 0);
- if (!gpu) {
- ret = 3;
- goto out_device;
- }
+ do {
+ gpu = etna_gpu_new(dev, core);
+ if (!gpu) {
+ perror("etna_gpu_new");
+ ret = 3;
+ goto out_device;
+ }
+
+ if (etna_gpu_get_param(gpu, ETNA_GPU_FEATURES_0, &feat)) {
+ perror("etna_gpu_get_param");
+ ret = 4;
+ goto out_device;
+ }
+
+ if ((feat & (1 << 9)) == 0) {
+ /* GPU not 2D capable. */
+ etna_gpu_del(gpu);
+ gpu = NULL;
+ }
+
+ core++;
+ } while (!gpu);
pipe = etna_pipe_new(gpu, ETNA_PIPE_2D);
if (!pipe) {
+ perror("etna_pipe_new");
ret = 4;
goto out_gpu;
}
bmp = etna_bo_new(dev, bmp_size, ETNA_BO_UNCACHED);
if (!bmp) {
+ perror("etna_bo_new");
ret = 5;
goto out_pipe;
}
@@ -204,6 +253,7 @@ int main(int argc, char *argv[])
stream = etna_cmd_stream_new(pipe, 0x300, NULL, NULL);
if (!stream) {
+ perror("etna_cmd_stream_new");
ret = 6;
goto out_bo;
}
@@ -213,7 +263,11 @@ int main(int argc, char *argv[])
etna_cmd_stream_finish(stream);
- bmp_dump32(etna_bo_map(bmp), width, height, false, "/tmp/etna.bmp");
+ if (argc > 2)
+ bmp_dump32(etna_bo_map(bmp), width, height, false, argv[2]);
+
+ if (etna_check_image(etna_bo_map(bmp), width, height))
+ ret = 7;
etna_cmd_stream_del(stream);
diff --git a/tests/etnaviv/etnaviv_bo_cache_test.c b/tests/etnaviv/etnaviv_bo_cache_test.c
index 7fb06293..904a5475 100644
--- a/tests/etnaviv/etnaviv_bo_cache_test.c
+++ b/tests/etnaviv/etnaviv_bo_cache_test.c
@@ -34,7 +34,7 @@
#include "xf86drm.h"
#include "etnaviv_drmif.h"
-#include "etnaviv_drm.h"
+#include <drm/etnaviv_drm.h>
static void test_cache(struct etna_device *dev)
{
diff --git a/tests/exynos/Makefile.am b/tests/exynos/Makefile.am
deleted file mode 100644
index 9658fb42..00000000
--- a/tests/exynos/Makefile.am
+++ /dev/null
@@ -1,48 +0,0 @@
-AM_CFLAGS = \
- -pthread \
- $(WARN_CFLAGS)\
- -fvisibility=hidden \
- -I $(top_srcdir)/include/drm \
- -I $(top_srcdir)/libkms/ \
- -I $(top_srcdir)/exynos \
- -I $(top_srcdir)
-
-bin_PROGRAMS =
-noinst_PROGRAMS =
-
-if HAVE_LIBKMS
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS += \
- exynos_fimg2d_test
-else
-noinst_PROGRAMS += \
- exynos_fimg2d_test
-endif
-endif
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS += \
- exynos_fimg2d_perf \
- exynos_fimg2d_event
-else
-noinst_PROGRAMS += \
- exynos_fimg2d_perf \
- exynos_fimg2d_event
-endif
-
-exynos_fimg2d_perf_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/exynos/libdrm_exynos.la
-
-exynos_fimg2d_event_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/exynos/libdrm_exynos.la
-
-exynos_fimg2d_test_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/libkms/libkms.la \
- $(top_builddir)/exynos/libdrm_exynos.la
-
-exynos_fimg2d_test_SOURCES = \
- exynos_fimg2d_test.c
-
diff --git a/tests/kms/Makefile.am b/tests/kms/Makefile.am
deleted file mode 100644
index 42242006..00000000
--- a/tests/kms/Makefile.am
+++ /dev/null
@@ -1,37 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/tests \
- -I$(top_srcdir)
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden
-
-noinst_LTLIBRARIES = libkms-test.la
-
-libkms_test_la_SOURCES = \
- libkms-test.h \
- libkms-test-crtc.c \
- libkms-test-device.c \
- libkms-test-framebuffer.c \
- libkms-test-plane.c \
- libkms-test-screen.c
-
-libkms_test_la_LIBADD = \
- $(top_builddir)/libdrm.la
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- kms-steal-crtc \
- kms-universal-planes
-else
-noinst_PROGRAMS = \
- kms-steal-crtc \
- kms-universal-planes
-endif
-
-kms_steal_crtc_SOURCES = kms-steal-crtc.c
-kms_steal_crtc_LDADD = libkms-test.la ../util/libutil.la $(CAIRO_LIBS)
-
-kms_universal_planes_SOURCES = kms-universal-planes.c
-kms_universal_planes_LDADD = libkms-test.la $(CAIRO_LIBS)
diff --git a/tests/kms/kms-steal-crtc.c b/tests/kms/kms-steal-crtc.c
index cd40758d..4d884c07 100644
--- a/tests/kms/kms-steal-crtc.c
+++ b/tests/kms/kms-steal-crtc.c
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <string.h>
#include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
+#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
diff --git a/tests/kms/kms-universal-planes.c b/tests/kms/kms-universal-planes.c
index 2163c987..1d793880 100644
--- a/tests/kms/kms-universal-planes.c
+++ b/tests/kms/kms-universal-planes.c
@@ -28,7 +28,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
+#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
diff --git a/tests/kms/libkms-test-screen.c b/tests/kms/libkms-test-screen.c
index bbe972a0..d00ae547 100644
--- a/tests/kms/libkms-test-screen.c
+++ b/tests/kms/libkms-test-screen.c
@@ -42,7 +42,9 @@ static void kms_screen_probe(struct kms_screen *screen)
else
screen->connected = false;
- memcpy(&screen->mode, &con->modes[0], sizeof(drmModeModeInfo));
+ if (con->modes)
+ memcpy(&screen->mode, &con->modes[0], sizeof(drmModeModeInfo));
+
screen->width = screen->mode.hdisplay;
screen->height = screen->mode.vdisplay;
diff --git a/tests/kmstest/Makefile.am b/tests/kmstest/Makefile.am
deleted file mode 100644
index 4c993b04..00000000
--- a/tests/kmstest/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-AM_CFLAGS = \
- $(WARN_CFLAGS)\
- -fvisibility=hidden \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/libkms/ \
- -I$(top_srcdir)/tests/ \
- -I$(top_srcdir)
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- kmstest
-else
-noinst_PROGRAMS = \
- kmstest
-endif
-
-kmstest_SOURCES = \
- main.c
-
-kmstest_LDADD = \
- $(top_builddir)/tests/util/libutil.la \
- $(top_builddir)/libkms/libkms.la \
- $(top_builddir)/libdrm.la
-
-run: kmstest
- ./kmstest
diff --git a/tests/meson.build b/tests/meson.build
index 6c8ddd9c..196edbfa 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -64,23 +64,15 @@ hash = executable(
c_args : libdrm_c_args,
)
-random = executable(
- 'random',
- files('random.c'),
- include_directories : [inc_root, inc_drm],
- link_with : libdrm,
- c_args : libdrm_c_args,
-)
-
drmdevice = executable(
'drmdevice',
files('drmdevice.c'),
include_directories : [inc_root, inc_drm],
link_with : libdrm,
c_args : libdrm_c_args,
+ install : with_install_tests,
)
-test('random', random, timeout : 240)
test('hash', hash)
test('drmsl', drmsl)
test('drmdevice', drmdevice)
diff --git a/tests/modeprint/Makefile.am b/tests/modeprint/Makefile.am
deleted file mode 100644
index 568185f0..00000000
--- a/tests/modeprint/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-AM_CFLAGS = \
- $(WARN_CFLAGS)\
- -fvisibility=hidden \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/tests \
- -I$(top_srcdir)
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- modeprint
-else
-noinst_PROGRAMS = \
- modeprint
-endif
-
-modeprint_SOURCES = \
- modeprint.c
-modeprint_LDADD = \
- $(top_builddir)/tests/util/libutil.la \
- $(top_builddir)/libdrm.la
diff --git a/tests/modetest/Android.bp b/tests/modetest/Android.bp
index ca811fee..02a17fe9 100644
--- a/tests/modetest/Android.bp
+++ b/tests/modetest/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_test {
diff --git a/tests/modetest/Makefile.am b/tests/modetest/Makefile.am
deleted file mode 100644
index 5eebd960..00000000
--- a/tests/modetest/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-include Makefile.sources
-
-AM_CFLAGS = $(filter-out -Wpointer-arith, $(WARN_CFLAGS))
-
-AM_CFLAGS += \
- -fvisibility=hidden \
- -pthread \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/tests \
- -I$(top_srcdir)
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- modetest
-else
-noinst_PROGRAMS = \
- modetest
-endif
-
-modetest_SOURCES = $(MODETEST_FILES)
-
-modetest_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/tests/util/libutil.la \
- $(CAIRO_LIBS)
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index e66be660..fc75383a 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -51,9 +51,10 @@
#include <errno.h>
#include <poll.h>
#include <sys/time.h>
-#ifdef HAVE_SYS_SELECT_H
+#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
+#include <math.h>
#include "xf86drm.h"
#include "xf86drmMode.h"
@@ -99,14 +100,16 @@ struct plane {
};
struct resources {
- drmModeRes *res;
- drmModePlaneRes *plane_res;
-
struct crtc *crtcs;
+ int count_crtcs;
struct encoder *encoders;
+ int count_encoders;
struct connector *connectors;
+ int count_connectors;
struct fb *fbs;
+ int count_fbs;
struct plane *planes;
+ uint32_t count_planes;
};
struct device {
@@ -132,6 +135,12 @@ static inline int64_t U642I64(uint64_t val)
return (int64_t)*((int64_t *)&val);
}
+static float mode_vrefresh(drmModeModeInfo *mode)
+{
+ return mode->clock * 1000.00
+ / (mode->htotal * mode->vtotal);
+}
+
#define bit_name_fn(res) \
const char * res##_str(int type) { \
unsigned int i; \
@@ -192,7 +201,7 @@ static void dump_encoders(struct device *dev)
printf("Encoders:\n");
printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n");
- for (i = 0; i < dev->resources->res->count_encoders; i++) {
+ for (i = 0; i < dev->resources->count_encoders; i++) {
encoder = dev->resources->encoders[i].encoder;
if (!encoder)
continue;
@@ -207,11 +216,12 @@ static void dump_encoders(struct device *dev)
printf("\n");
}
-static void dump_mode(drmModeModeInfo *mode)
+static void dump_mode(drmModeModeInfo *mode, int index)
{
- printf(" %s %d %d %d %d %d %d %d %d %d %d",
+ printf(" #%i %s %.2f %d %d %d %d %d %d %d %d %d",
+ index,
mode->name,
- mode->vrefresh,
+ mode_vrefresh(mode),
mode->hdisplay,
mode->hsync_start,
mode->hsync_end,
@@ -426,7 +436,7 @@ static void dump_connectors(struct device *dev)
printf("Connectors:\n");
printf("id\tencoder\tstatus\t\tname\t\tsize (mm)\tmodes\tencoders\n");
- for (i = 0; i < dev->resources->res->count_connectors; i++) {
+ for (i = 0; i < dev->resources->count_connectors; i++) {
struct connector *_connector = &dev->resources->connectors[i];
drmModeConnector *connector = _connector->connector;
if (!connector)
@@ -446,10 +456,10 @@ static void dump_connectors(struct device *dev)
if (connector->count_modes) {
printf(" modes:\n");
- printf("\tname refresh (Hz) hdisp hss hse htot vdisp "
- "vss vse vtot)\n");
+ printf("\tindex name refresh (Hz) hdisp hss hse htot vdisp "
+ "vss vse vtot\n");
for (j = 0; j < connector->count_modes; j++)
- dump_mode(&connector->modes[j]);
+ dump_mode(&connector->modes[j], j);
}
if (_connector->props) {
@@ -470,7 +480,7 @@ static void dump_crtcs(struct device *dev)
printf("CRTCs:\n");
printf("id\tfb\tpos\tsize\n");
- for (i = 0; i < dev->resources->res->count_crtcs; i++) {
+ for (i = 0; i < dev->resources->count_crtcs; i++) {
struct crtc *_crtc = &dev->resources->crtcs[i];
drmModeCrtc *crtc = _crtc->crtc;
if (!crtc)
@@ -481,7 +491,7 @@ static void dump_crtcs(struct device *dev)
crtc->buffer_id,
crtc->x, crtc->y,
crtc->width, crtc->height);
- dump_mode(&crtc->mode);
+ dump_mode(&crtc->mode, 0);
if (_crtc->props) {
printf(" props:\n");
@@ -503,7 +513,7 @@ static void dump_framebuffers(struct device *dev)
printf("Frame buffers:\n");
printf("id\tsize\tpitch\n");
- for (i = 0; i < dev->resources->res->count_fbs; i++) {
+ for (i = 0; i < dev->resources->count_fbs; i++) {
fb = dev->resources->fbs[i].fb;
if (!fb)
continue;
@@ -523,10 +533,7 @@ static void dump_planes(struct device *dev)
printf("Planes:\n");
printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\tpossible crtcs\n");
- if (!dev->resources->plane_res)
- return;
-
- for (i = 0; i < dev->resources->plane_res->count_planes; i++) {
+ for (i = 0; i < dev->resources->count_planes; i++) {
struct plane *plane = &dev->resources->planes[i];
drmModePlane *ovr = plane->plane;
if (!ovr)
@@ -567,11 +574,11 @@ static void free_resources(struct resources *res)
if (!res)
return;
-#define free_resource(_res, __res, type, Type) \
+#define free_resource(_res, type, Type) \
do { \
if (!(_res)->type##s) \
break; \
- for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
+ for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \
if (!(_res)->type##s[i].type) \
break; \
drmModeFree##Type((_res)->type##s[i].type); \
@@ -579,42 +586,38 @@ static void free_resources(struct resources *res)
free((_res)->type##s); \
} while (0)
-#define free_properties(_res, __res, type) \
+#define free_properties(_res, type) \
do { \
- for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
- drmModeFreeObjectProperties(res->type##s[i].props); \
+ for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \
+ unsigned int j; \
+ for (j = 0; j < res->type##s[i].props->count_props; ++j)\
+ drmModeFreeProperty(res->type##s[i].props_info[j]);\
free(res->type##s[i].props_info); \
+ drmModeFreeObjectProperties(res->type##s[i].props); \
} \
} while (0)
- if (res->res) {
- free_properties(res, res, crtc);
-
- free_resource(res, res, crtc, Crtc);
- free_resource(res, res, encoder, Encoder);
+ free_properties(res, plane);
+ free_resource(res, plane, Plane);
- for (i = 0; i < res->res->count_connectors; i++)
- free(res->connectors[i].name);
+ free_properties(res, connector);
+ free_properties(res, crtc);
- free_resource(res, res, connector, Connector);
- free_resource(res, res, fb, FB);
+ for (i = 0; i < res->count_connectors; i++)
+ free(res->connectors[i].name);
- drmModeFreeResources(res->res);
- }
-
- if (res->plane_res) {
- free_properties(res, plane_res, plane);
-
- free_resource(res, plane_res, plane, Plane);
-
- drmModeFreePlaneResources(res->plane_res);
- }
+ free_resource(res, fb, FB);
+ free_resource(res, connector, Connector);
+ free_resource(res, encoder, Encoder);
+ free_resource(res, crtc, Crtc);
free(res);
}
static struct resources *get_resources(struct device *dev)
{
+ drmModeRes *_res;
+ drmModePlaneRes *plane_res;
struct resources *res;
int i;
@@ -624,40 +627,51 @@ static struct resources *get_resources(struct device *dev)
drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
- res->res = drmModeGetResources(dev->fd);
- if (!res->res) {
+ _res = drmModeGetResources(dev->fd);
+ if (!_res) {
fprintf(stderr, "drmModeGetResources failed: %s\n",
strerror(errno));
- goto error;
+ free(res);
+ return NULL;
}
- res->crtcs = calloc(res->res->count_crtcs, sizeof(*res->crtcs));
- res->encoders = calloc(res->res->count_encoders, sizeof(*res->encoders));
- res->connectors = calloc(res->res->count_connectors, sizeof(*res->connectors));
- res->fbs = calloc(res->res->count_fbs, sizeof(*res->fbs));
+ res->count_crtcs = _res->count_crtcs;
+ res->count_encoders = _res->count_encoders;
+ res->count_connectors = _res->count_connectors;
+ res->count_fbs = _res->count_fbs;
- if (!res->crtcs || !res->encoders || !res->connectors || !res->fbs)
+ res->crtcs = calloc(res->count_crtcs, sizeof(*res->crtcs));
+ res->encoders = calloc(res->count_encoders, sizeof(*res->encoders));
+ res->connectors = calloc(res->count_connectors, sizeof(*res->connectors));
+ res->fbs = calloc(res->count_fbs, sizeof(*res->fbs));
+
+ if (!res->crtcs || !res->encoders || !res->connectors || !res->fbs) {
+ drmModeFreeResources(_res);
goto error;
+ }
#define get_resource(_res, __res, type, Type) \
do { \
- for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
- (_res)->type##s[i].type = \
- drmModeGet##Type(dev->fd, (_res)->__res->type##s[i]); \
- if (!(_res)->type##s[i].type) \
+ for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \
+ uint32_t type##id = (__res)->type##s[i]; \
+ (_res)->type##s[i].type = \
+ drmModeGet##Type(dev->fd, type##id); \
+ if (!(_res)->type##s[i].type) \
fprintf(stderr, "could not get %s %i: %s\n", \
- #type, (_res)->__res->type##s[i], \
+ #type, type##id, \
strerror(errno)); \
} \
} while (0)
- get_resource(res, res, crtc, Crtc);
- get_resource(res, res, encoder, Encoder);
- get_resource(res, res, connector, Connector);
- get_resource(res, res, fb, FB);
+ get_resource(res, _res, crtc, Crtc);
+ get_resource(res, _res, encoder, Encoder);
+ get_resource(res, _res, connector, Connector);
+ get_resource(res, _res, fb, FB);
+
+ drmModeFreeResources(_res);
/* Set the name of all connectors based on the type name and the per-type ID. */
- for (i = 0; i < res->res->count_connectors; i++) {
+ for (i = 0; i < res->count_connectors; i++) {
struct connector *connector = &res->connectors[i];
drmModeConnector *conn = connector->connector;
int num;
@@ -669,9 +683,9 @@ static struct resources *get_resources(struct device *dev)
goto error;
}
-#define get_properties(_res, __res, type, Type) \
+#define get_properties(_res, type, Type) \
do { \
- for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
+ for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \
struct type *obj = &res->type##s[i]; \
unsigned int j; \
obj->props = \
@@ -694,25 +708,30 @@ static struct resources *get_resources(struct device *dev)
} \
} while (0)
- get_properties(res, res, crtc, CRTC);
- get_properties(res, res, connector, CONNECTOR);
+ get_properties(res, crtc, CRTC);
+ get_properties(res, connector, CONNECTOR);
- for (i = 0; i < res->res->count_crtcs; ++i)
+ for (i = 0; i < res->count_crtcs; ++i)
res->crtcs[i].mode = &res->crtcs[i].crtc->mode;
- res->plane_res = drmModeGetPlaneResources(dev->fd);
- if (!res->plane_res) {
+ plane_res = drmModeGetPlaneResources(dev->fd);
+ if (!plane_res) {
fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
strerror(errno));
return res;
}
- res->planes = calloc(res->plane_res->count_planes, sizeof(*res->planes));
- if (!res->planes)
+ res->count_planes = plane_res->count_planes;
+
+ res->planes = calloc(res->count_planes, sizeof(*res->planes));
+ if (!res->planes) {
+ drmModeFreePlaneResources(plane_res);
goto error;
+ }
get_resource(res, plane_res, plane, Plane);
- get_properties(res, plane_res, plane, PLANE);
+ drmModeFreePlaneResources(plane_res);
+ get_properties(res, plane, PLANE);
return res;
@@ -721,17 +740,31 @@ error:
return NULL;
}
-static int get_crtc_index(struct device *dev, uint32_t id)
+static struct crtc *get_crtc_by_id(struct device *dev, uint32_t id)
{
int i;
- for (i = 0; i < dev->resources->res->count_crtcs; ++i) {
+ for (i = 0; i < dev->resources->count_crtcs; ++i) {
drmModeCrtc *crtc = dev->resources->crtcs[i].crtc;
if (crtc && crtc->crtc_id == id)
- return i;
+ return &dev->resources->crtcs[i];
}
- return -1;
+ return NULL;
+}
+
+static uint32_t get_crtc_mask(struct device *dev, struct crtc *crtc)
+{
+ unsigned int i;
+
+ for (i = 0; i < (unsigned int)dev->resources->count_crtcs; i++) {
+ if (crtc->crtc->crtc_id == dev->resources->crtcs[i].crtc->crtc_id)
+ return 1 << i;
+ }
+ /* Unreachable: crtc->crtc is one of resources->crtcs[] */
+ /* Don't return zero or static analysers will complain */
+ abort();
+ return 0;
}
static drmModeConnector *get_connector_by_name(struct device *dev, const char *name)
@@ -739,7 +772,7 @@ static drmModeConnector *get_connector_by_name(struct device *dev, const char *n
struct connector *connector;
int i;
- for (i = 0; i < dev->resources->res->count_connectors; i++) {
+ for (i = 0; i < dev->resources->count_connectors; i++) {
connector = &dev->resources->connectors[i];
if (strcmp(connector->name, name) == 0)
@@ -754,7 +787,7 @@ static drmModeConnector *get_connector_by_id(struct device *dev, uint32_t id)
drmModeConnector *connector;
int i;
- for (i = 0; i < dev->resources->res->count_connectors; i++) {
+ for (i = 0; i < dev->resources->count_connectors; i++) {
connector = dev->resources->connectors[i].connector;
if (connector && connector->connector_id == id)
return connector;
@@ -768,7 +801,7 @@ static drmModeEncoder *get_encoder_by_id(struct device *dev, uint32_t id)
drmModeEncoder *encoder;
int i;
- for (i = 0; i < dev->resources->res->count_encoders; i++) {
+ for (i = 0; i < dev->resources->count_encoders; i++) {
encoder = dev->resources->encoders[i].encoder;
if (encoder && encoder->encoder_id == id)
return encoder;
@@ -795,7 +828,7 @@ struct pipe_arg {
uint32_t crtc_id;
char mode_str[64];
char format_str[5];
- unsigned int vrefresh;
+ float vrefresh;
unsigned int fourcc;
drmModeModeInfo *mode;
struct crtc *crtc;
@@ -822,7 +855,7 @@ struct plane_arg {
static drmModeModeInfo *
connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str,
- const unsigned int vrefresh)
+ const float vrefresh)
{
drmModeConnector *connector;
drmModeModeInfo *mode;
@@ -832,16 +865,27 @@ connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str,
if (!connector || !connector->count_modes)
return NULL;
+ /* Pick by Index */
+ if (mode_str[0] == '#') {
+ int index = atoi(mode_str + 1);
+
+ if (index >= connector->count_modes || index < 0)
+ return NULL;
+ return &connector->modes[index];
+ }
+
+ /* Pick by Name */
for (i = 0; i < connector->count_modes; i++) {
mode = &connector->modes[i];
if (!strcmp(mode->name, mode_str)) {
- /* If the vertical refresh frequency is not specified then return the
- * first mode that match with the name. Else, return the mode that match
- * the name and the specified vertical refresh frequency.
+ /* If the vertical refresh frequency is not specified
+ * then return the first mode that match with the name.
+ * Else, return the mode that match the name and
+ * the specified vertical refresh frequency.
*/
if (vrefresh == 0)
return mode;
- else if (mode->vrefresh == vrefresh)
+ else if (fabs(mode_vrefresh(mode) - vrefresh) < 0.005)
return mode;
}
}
@@ -861,7 +905,7 @@ static struct crtc *pipe_find_crtc(struct device *dev, struct pipe_arg *pipe)
uint32_t crtcs_for_connector = 0;
drmModeConnector *connector;
drmModeEncoder *encoder;
- int idx;
+ struct crtc *crtc;
connector = get_connector_by_id(dev, pipe->con_ids[i]);
if (!connector)
@@ -873,10 +917,10 @@ static struct crtc *pipe_find_crtc(struct device *dev, struct pipe_arg *pipe)
continue;
crtcs_for_connector |= encoder->possible_crtcs;
-
- idx = get_crtc_index(dev, encoder->crtc_id);
- if (idx >= 0)
- active_crtcs |= 1 << idx;
+ crtc = get_crtc_by_id(dev, encoder->crtc_id);
+ if (!crtc)
+ continue;
+ active_crtcs |= get_crtc_mask(dev, crtc);
}
possible_crtcs &= crtcs_for_connector;
@@ -907,7 +951,13 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe)
mode = connector_find_mode(dev, pipe->con_ids[i],
pipe->mode_str, pipe->vrefresh);
if (mode == NULL) {
- fprintf(stderr,
+ if (pipe->vrefresh)
+ fprintf(stderr,
+ "failed to find mode "
+ "\"%s-%.2fHz\" for connector %s\n",
+ pipe->mode_str, pipe->vrefresh, pipe->cons[i]);
+ else
+ fprintf(stderr,
"failed to find mode \"%s\" for connector %s\n",
pipe->mode_str, pipe->cons[i]);
return -EINVAL;
@@ -918,16 +968,10 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe)
* locate a CRTC that can be attached to all the connectors.
*/
if (pipe->crtc_id != (uint32_t)-1) {
- for (i = 0; i < dev->resources->res->count_crtcs; i++) {
- struct crtc *crtc = &dev->resources->crtcs[i];
-
- if (pipe->crtc_id == crtc->crtc->crtc_id) {
- pipe->crtc = crtc;
- break;
- }
- }
+ pipe->crtc = get_crtc_by_id(dev, pipe->crtc_id);
} else {
pipe->crtc = pipe_find_crtc(dev, pipe);
+ pipe->crtc_id = pipe->crtc->crtc->crtc_id;
}
if (!pipe->crtc) {
@@ -965,9 +1009,9 @@ static bool set_property(struct device *dev, struct property_arg *p)
p->obj_type = 0;
p->prop_id = 0;
-#define find_object(_res, __res, type, Type) \
+#define find_object(_res, type, Type) \
do { \
- for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \
+ for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \
struct type *obj = &(_res)->type##s[i]; \
if (obj->type->type##_id != p->obj_id) \
continue; \
@@ -978,11 +1022,11 @@ static bool set_property(struct device *dev, struct property_arg *p)
} \
} while(0) \
- find_object(dev->resources, res, crtc, CRTC);
+ find_object(dev->resources, crtc, CRTC);
if (p->obj_type == 0)
- find_object(dev->resources, res, connector, CONNECTOR);
+ find_object(dev->resources, connector, CONNECTOR);
if (p->obj_type == 0)
- find_object(dev->resources, plane_res, plane, PLANE);
+ find_object(dev->resources, plane, PLANE);
if (p->obj_type == 0) {
fprintf(stderr, "Object %i not found, can't set property\n",
p->obj_id);
@@ -1041,7 +1085,7 @@ page_flip_handler(int fd, unsigned int frame,
else
new_fb_id = pipe->fb_id[0];
- drmModePageFlip(fd, pipe->crtc->crtc->crtc_id, new_fb_id,
+ drmModePageFlip(fd, pipe->crtc_id, new_fb_id,
DRM_MODE_PAGE_FLIP_EVENT, pipe);
pipe->current_fb_id = new_fb_id;
pipe->swap_count++;
@@ -1128,26 +1172,41 @@ static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
}
}
+static int
+bo_fb_create(int fd, unsigned int fourcc, const uint32_t w, const uint32_t h,
+ enum util_fill_pattern pat, struct bo **out_bo, unsigned int *out_fb_id)
+{
+ uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
+ struct bo *bo;
+ unsigned int fb_id;
+
+ bo = bo_create(fd, fourcc, w, h, handles, pitches, offsets, pat);
+
+ if (bo == NULL)
+ return -1;
+
+ if (drmModeAddFB2(fd, w, h, fourcc, handles, pitches, offsets, &fb_id, 0)) {
+ fprintf(stderr, "failed to add fb (%ux%u): %s\n", w, h, strerror(errno));
+ bo_destroy(bo);
+ return -1;
+ }
+ *out_bo = bo;
+ *out_fb_id = fb_id;
+ return 0;
+}
+
static int atomic_set_plane(struct device *dev, struct plane_arg *p,
int pattern, bool update)
{
- uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
struct bo *plane_bo;
int crtc_x, crtc_y, crtc_w, crtc_h;
struct crtc *crtc = NULL;
- unsigned int i;
unsigned int old_fb_id;
/* Find an unused plane which can be connected to our CRTC. Find the
* CRTC index first, then iterate over available planes.
*/
- for (i = 0; i < (unsigned int)dev->resources->res->count_crtcs; i++) {
- if (p->crtc_id == dev->resources->res->crtcs[i]) {
- crtc = &dev->resources->crtcs[i];
- break;
- }
- }
-
+ crtc = get_crtc_by_id(dev, p->crtc_id);
if (!crtc) {
fprintf(stderr, "CRTC %u not found\n", p->crtc_id);
return -1;
@@ -1161,17 +1220,9 @@ static int atomic_set_plane(struct device *dev, struct plane_arg *p,
p->old_bo = p->bo;
if (!plane_bo) {
- plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h,
- handles, pitches, offsets, pattern);
-
- if (plane_bo == NULL)
- return -1;
-
- if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc,
- handles, pitches, offsets, &p->fb_id, 0)) {
- fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
+ if (bo_fb_create(dev->fd, p->fourcc, p->w, p->h,
+ pattern, &plane_bo, &p->fb_id))
return -1;
- }
}
p->bo = plane_bo;
@@ -1207,34 +1258,23 @@ static int atomic_set_plane(struct device *dev, struct plane_arg *p,
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;
- struct bo *plane_bo;
- uint32_t plane_flags = 0;
int crtc_x, crtc_y, crtc_w, crtc_h;
struct crtc *crtc = NULL;
- unsigned int pipe;
- unsigned int i;
+ unsigned int i, crtc_mask;
/* Find an unused plane which can be connected to our CRTC. Find the
* CRTC index first, then iterate over available planes.
*/
- for (i = 0; i < (unsigned int)dev->resources->res->count_crtcs; i++) {
- if (p->crtc_id == dev->resources->res->crtcs[i]) {
- crtc = &dev->resources->crtcs[i];
- pipe = i;
- break;
- }
- }
-
+ crtc = get_crtc_by_id(dev, p->crtc_id);
if (!crtc) {
fprintf(stderr, "CRTC %u not found\n", p->crtc_id);
return -1;
}
-
+ crtc_mask = get_crtc_mask(dev, crtc);
plane_id = p->plane_id;
- for (i = 0; i < dev->resources->plane_res->count_planes; i++) {
+ for (i = 0; i < dev->resources->count_planes; i++) {
ovr = dev->resources->planes[i].plane;
if (!ovr)
continue;
@@ -1245,35 +1285,26 @@ static int set_plane(struct device *dev, struct plane_arg *p)
if (!format_support(ovr, p->fourcc))
continue;
- if ((ovr->possible_crtcs & (1 << pipe)) &&
+ if ((ovr->possible_crtcs & crtc_mask) &&
(ovr->crtc_id == 0 || ovr->crtc_id == p->crtc_id)) {
plane_id = ovr->plane_id;
break;
}
}
- if (i == dev->resources->plane_res->count_planes) {
+ if (i == dev->resources->count_planes) {
fprintf(stderr, "no unused plane available for CRTC %u\n",
- crtc->crtc->crtc_id);
+ p->crtc_id);
return -1;
}
fprintf(stderr, "testing %dx%d@%s overlay plane %u\n",
p->w, p->h, p->format_str, plane_id);
- plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, handles,
- pitches, offsets, secondary_fill);
- if (plane_bo == NULL)
- return -1;
-
- p->bo = plane_bo;
-
/* just use single plane format for now.. */
- if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc,
- handles, pitches, offsets, &p->fb_id, plane_flags)) {
- fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
+ if (bo_fb_create(dev->fd, p->fourcc, p->w, p->h,
+ secondary_fill, &p->bo, &p->fb_id))
return -1;
- }
crtc_w = p->w * p->scale;
crtc_h = p->h * p->scale;
@@ -1287,15 +1318,15 @@ static int set_plane(struct device *dev, struct plane_arg *p)
}
/* note src coords (last 4 args) are in Q16 format */
- if (drmModeSetPlane(dev->fd, plane_id, crtc->crtc->crtc_id, p->fb_id,
- plane_flags, crtc_x, crtc_y, crtc_w, crtc_h,
+ if (drmModeSetPlane(dev->fd, plane_id, p->crtc_id, p->fb_id,
+ 0, crtc_x, crtc_y, crtc_w, crtc_h,
0, 0, p->w << 16, p->h << 16)) {
fprintf(stderr, "failed to enable plane: %s\n",
strerror(errno));
return -1;
}
- ovr->crtc_id = crtc->crtc->crtc_id;
+ ovr->crtc_id = p->crtc_id;
return 0;
}
@@ -1317,6 +1348,41 @@ static void atomic_set_planes(struct device *dev, struct plane_arg *p,
}
}
+static void
+atomic_test_page_flip(struct device *dev, struct pipe_arg *pipe_args,
+ struct plane_arg *plane_args, unsigned int plane_count)
+{
+ int ret;
+
+ gettimeofday(&pipe_args->start, NULL);
+ pipe_args->swap_count = 0;
+
+ while (true) {
+ drmModeAtomicFree(dev->req);
+ dev->req = drmModeAtomicAlloc();
+ atomic_set_planes(dev, plane_args, plane_count, true);
+
+ ret = drmModeAtomicCommit(dev->fd, dev->req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ if (ret) {
+ fprintf(stderr, "Atomic Commit failed [2]\n");
+ return;
+ }
+
+ pipe_args->swap_count++;
+ if (pipe_args->swap_count == 60) {
+ struct timeval end;
+ double t;
+
+ gettimeofday(&end, NULL);
+ t = end.tv_sec + end.tv_usec * 1e-6 -
+ (pipe_args->start.tv_sec + pipe_args->start.tv_usec * 1e-6);
+ fprintf(stderr, "freq: %.02fHz\n", pipe_args->swap_count / t);
+ pipe_args->swap_count = 0;
+ pipe_args->start = end;
+ }
+ }
+}
+
static void atomic_clear_planes(struct device *dev, struct plane_arg *p, unsigned int count)
{
unsigned int i;
@@ -1372,131 +1438,269 @@ static void clear_planes(struct device *dev, struct plane_arg *p, unsigned int c
}
}
-static void atomic_set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
+static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
{
+ drmModeConnector *connector;
unsigned int i;
- unsigned int j;
- int ret;
+ uint32_t id;
+ char *endp;
- for (i = 0; i < count; i++) {
- struct pipe_arg *pipe = &pipes[i];
+ for (i = 0; i < pipe->num_cons; i++) {
+ id = strtoul(pipe->cons[i], &endp, 10);
+ if (endp == pipe->cons[i]) {
+ connector = get_connector_by_name(dev, pipe->cons[i]);
+ if (!connector) {
+ fprintf(stderr, "no connector named '%s'\n",
+ pipe->cons[i]);
+ return -ENODEV;
+ }
- ret = pipe_find_crtc_and_mode(dev, pipe);
- if (ret < 0)
+ id = connector->connector_id;
+ }
+
+ pipe->con_ids[i] = id;
+ }
+
+ return 0;
+}
+
+static int pipe_attempt_connector(struct device *dev, drmModeConnector *con,
+ struct pipe_arg *pipe)
+{
+ char *con_str;
+ int i;
+
+ con_str = calloc(8, sizeof(char));
+ if (!con_str)
+ return -1;
+
+ sprintf(con_str, "%d", con->connector_id);
+ strcpy(pipe->format_str, "XR24");
+ pipe->fourcc = util_format_fourcc(pipe->format_str);
+ pipe->num_cons = 1;
+ pipe->con_ids = calloc(1, sizeof(*pipe->con_ids));
+ pipe->cons = calloc(1, sizeof(*pipe->cons));
+
+ if (!pipe->con_ids || !pipe->cons)
+ goto free_con_str;
+
+ pipe->con_ids[0] = con->connector_id;
+ pipe->cons[0] = (const char*)con_str;
+
+ pipe->crtc = pipe_find_crtc(dev, pipe);
+ if (!pipe->crtc)
+ goto free_all;
+
+ pipe->crtc_id = pipe->crtc->crtc->crtc_id;
+
+ /* Return the first mode if no preferred. */
+ pipe->mode = &con->modes[0];
+
+ for (i = 0; i < con->count_modes; i++) {
+ drmModeModeInfo *current_mode = &con->modes[i];
+
+ if (current_mode->type & DRM_MODE_TYPE_PREFERRED) {
+ pipe->mode = current_mode;
+ break;
+ }
+ }
+
+ sprintf(pipe->mode_str, "%dx%d", pipe->mode->hdisplay, pipe->mode->vdisplay);
+
+ return 0;
+
+free_all:
+ free(pipe->cons);
+ free(pipe->con_ids);
+free_con_str:
+ free(con_str);
+ return -1;
+}
+
+static int pipe_find_preferred(struct device *dev, struct pipe_arg **out_pipes)
+{
+ struct pipe_arg *pipes;
+ struct resources *res = dev->resources;
+ drmModeConnector *con = NULL;
+ int i, connected = 0, attempted = 0;
+
+ for (i = 0; i < res->count_connectors; i++) {
+ con = res->connectors[i].connector;
+ if (!con || con->connection != DRM_MODE_CONNECTED)
continue;
+ connected++;
+ }
+ if (!connected) {
+ printf("no connected connector!\n");
+ return 0;
}
- for (i = 0; i < count; i++) {
- struct pipe_arg *pipe = &pipes[i];
- uint32_t blob_id;
+ pipes = calloc(connected, sizeof(struct pipe_arg));
+ if (!pipes)
+ return 0;
- if (pipe->mode == NULL)
+ for (i = 0; i < res->count_connectors && attempted < connected; i++) {
+ con = res->connectors[i].connector;
+ if (!con || con->connection != DRM_MODE_CONNECTED)
continue;
- printf("setting mode %s-%dHz on connectors ",
- pipe->mode_str, pipe->mode->vrefresh);
- for (j = 0; j < pipe->num_cons; ++j) {
- printf("%s, ", pipe->cons[j]);
- add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc->crtc->crtc_id);
+ if (pipe_attempt_connector(dev, con, &pipes[attempted]) < 0) {
+ printf("failed fetching preferred mode for connector\n");
+ continue;
}
- printf("crtc %d\n", pipe->crtc->crtc->crtc_id);
-
- drmModeCreatePropertyBlob(dev->fd, pipe->mode, sizeof(*pipe->mode), &blob_id);
- add_property(dev, pipe->crtc->crtc->crtc_id, "MODE_ID", blob_id);
- add_property(dev, pipe->crtc->crtc->crtc_id, "ACTIVE", 1);
+ attempted++;
}
+
+ *out_pipes = pipes;
+ return attempted;
}
-static void atomic_clear_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
+static struct plane *get_primary_plane_by_crtc(struct device *dev, struct crtc *crtc)
{
unsigned int i;
- unsigned int j;
- for (i = 0; i < count; i++) {
- struct pipe_arg *pipe = &pipes[i];
-
- if (pipe->mode == NULL)
+ for (i = 0; i < dev->resources->count_planes; i++) {
+ struct plane *plane = &dev->resources->planes[i];
+ drmModePlane *ovr = plane->plane;
+ if (!ovr)
continue;
- for (j = 0; j < pipe->num_cons; ++j)
- add_property(dev, pipe->con_ids[j], "CRTC_ID",0);
+ // XXX: add is_primary_plane and (?) format checks
- add_property(dev, pipe->crtc->crtc->crtc_id, "MODE_ID", 0);
- add_property(dev, pipe->crtc->crtc->crtc_id, "ACTIVE", 0);
+ if (ovr->possible_crtcs & get_crtc_mask(dev, crtc))
+ return plane;
}
+ return NULL;
}
static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
{
- uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
- unsigned int fb_id;
- struct bo *bo;
- unsigned int i;
- unsigned int j;
- int ret, x;
-
- dev->mode.width = 0;
- dev->mode.height = 0;
- dev->mode.fb_id = 0;
+ unsigned int i, j;
+ int ret, x = 0;
+ int preferred = count == 0;
for (i = 0; i < count; i++) {
struct pipe_arg *pipe = &pipes[i];
+ ret = pipe_resolve_connectors(dev, pipe);
+ if (ret < 0)
+ return;
+
ret = pipe_find_crtc_and_mode(dev, pipe);
if (ret < 0)
continue;
+ }
+ if (preferred) {
+ struct pipe_arg *pipe_args;
- dev->mode.width += pipe->mode->hdisplay;
- if (dev->mode.height < pipe->mode->vdisplay)
- dev->mode.height = pipe->mode->vdisplay;
+ count = pipe_find_preferred(dev, &pipe_args);
+ if (!count) {
+ fprintf(stderr, "can't find any preferred connector/mode.\n");
+ return;
+ }
+ pipes = pipe_args;
}
- bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width,
- dev->mode.height, handles, pitches, offsets,
- primary_fill);
- if (bo == NULL)
- return;
+ if (!dev->use_atomic) {
+ for (i = 0; i < count; i++) {
+ struct pipe_arg *pipe = &pipes[i];
- dev->mode.bo = bo;
+ if (pipe->mode == NULL)
+ continue;
- ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height,
- pipes[0].fourcc, handles, pitches, offsets, &fb_id, 0);
- if (ret) {
- fprintf(stderr, "failed to add fb (%ux%u): %s\n",
- dev->mode.width, dev->mode.height, strerror(errno));
- return;
- }
+ if (!preferred) {
+ dev->mode.width += pipe->mode->hdisplay;
+ if (dev->mode.height < pipe->mode->vdisplay)
+ dev->mode.height = pipe->mode->vdisplay;
+ } else {
+ /* XXX: Use a clone mode, more like atomic. We could do per
+ * connector bo/fb, so we don't have the stretched image.
+ */
+ if (dev->mode.width < pipe->mode->hdisplay)
+ dev->mode.width = pipe->mode->hdisplay;
+ if (dev->mode.height < pipe->mode->vdisplay)
+ dev->mode.height = pipe->mode->vdisplay;
+ }
+ }
- dev->mode.fb_id = fb_id;
+ if (bo_fb_create(dev->fd, pipes[0].fourcc, dev->mode.width, dev->mode.height,
+ primary_fill, &dev->mode.bo, &dev->mode.fb_id))
+ return;
+ }
- x = 0;
for (i = 0; i < count; i++) {
struct pipe_arg *pipe = &pipes[i];
+ uint32_t blob_id;
if (pipe->mode == NULL)
continue;
- printf("setting mode %s-%dHz@%s on connectors ",
- pipe->mode_str, pipe->mode->vrefresh, pipe->format_str);
- for (j = 0; j < pipe->num_cons; ++j)
+ printf("setting mode %s-%.2fHz on connectors ",
+ pipe->mode->name, mode_vrefresh(pipe->mode));
+ for (j = 0; j < pipe->num_cons; ++j) {
printf("%s, ", pipe->cons[j]);
- printf("crtc %d\n", pipe->crtc->crtc->crtc_id);
+ if (dev->use_atomic)
+ add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc_id);
+ }
+ printf("crtc %d\n", pipe->crtc_id);
- ret = drmModeSetCrtc(dev->fd, pipe->crtc->crtc->crtc_id, fb_id,
- x, 0, pipe->con_ids, pipe->num_cons,
- pipe->mode);
+ if (!dev->use_atomic) {
+ ret = drmModeSetCrtc(dev->fd, pipe->crtc_id, dev->mode.fb_id,
+ x, 0, pipe->con_ids, pipe->num_cons,
+ pipe->mode);
- /* XXX: Actually check if this is needed */
- drmModeDirtyFB(dev->fd, fb_id, NULL, 0);
+ /* XXX: Actually check if this is needed */
+ drmModeDirtyFB(dev->fd, dev->mode.fb_id, NULL, 0);
- x += pipe->mode->hdisplay;
+ if (!preferred)
+ x += pipe->mode->hdisplay;
- if (ret) {
- fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
- return;
+ if (ret) {
+ fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
+ return;
+ }
+
+ set_gamma(dev, pipe->crtc_id, pipe->fourcc);
+ } else {
+ drmModeCreatePropertyBlob(dev->fd, pipe->mode, sizeof(*pipe->mode), &blob_id);
+ add_property(dev, pipe->crtc_id, "MODE_ID", blob_id);
+ add_property(dev, pipe->crtc_id, "ACTIVE", 1);
+
+ /* By default atomic modeset does not set a primary plane, shrug */
+ if (preferred) {
+ struct plane *plane = get_primary_plane_by_crtc(dev, pipe->crtc);
+ struct plane_arg plane_args = {
+ .plane_id = plane->plane->plane_id,
+ .crtc_id = pipe->crtc_id,
+ .w = pipe->mode->hdisplay,
+ .h = pipe->mode->vdisplay,
+ .scale = 1.0,
+ .format_str = "XR24",
+ .fourcc = util_format_fourcc(pipe->format_str),
+ };
+
+ atomic_set_planes(dev, &plane_args, 1, false);
+ }
}
+ }
+}
+
+static void atomic_clear_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
+{
+ unsigned int i;
+ unsigned int j;
+
+ for (i = 0; i < count; i++) {
+ struct pipe_arg *pipe = &pipes[i];
- set_gamma(dev, pipe->crtc->crtc->crtc_id, pipe->fourcc);
+ if (pipe->mode == NULL)
+ continue;
+
+ for (j = 0; j < pipe->num_cons; ++j)
+ add_property(dev, pipe->con_ids[j], "CRTC_ID",0);
+
+ add_property(dev, pipe->crtc_id, "MODE_ID", 0);
+ add_property(dev, pipe->crtc_id, "ACTIVE", 0);
}
}
@@ -1542,7 +1746,7 @@ static void set_cursors(struct device *dev, struct pipe_arg *pipes, unsigned int
for (i = 0; i < count; i++) {
struct pipe_arg *pipe = &pipes[i];
ret = cursor_init(dev->fd, handles[0],
- pipe->crtc->crtc->crtc_id,
+ pipe->crtc_id,
pipe->mode->hdisplay, pipe->mode->vdisplay,
cw, ch);
if (ret) {
@@ -1565,34 +1769,23 @@ static void clear_cursors(struct device *dev)
static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned int count)
{
- uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
unsigned int other_fb_id;
struct bo *other_bo;
drmEventContext evctx;
unsigned int i;
int ret;
- other_bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width,
- dev->mode.height, handles, pitches, offsets,
- UTIL_PATTERN_PLAIN);
- if (other_bo == NULL)
+ if (bo_fb_create(dev->fd, pipes[0].fourcc, dev->mode.width, dev->mode.height,
+ UTIL_PATTERN_PLAIN, &other_bo, &other_fb_id))
return;
- ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height,
- pipes[0].fourcc, handles, pitches, offsets,
- &other_fb_id, 0);
- if (ret) {
- fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
- goto err;
- }
-
for (i = 0; i < count; i++) {
struct pipe_arg *pipe = &pipes[i];
if (pipe->mode == NULL)
continue;
- ret = drmModePageFlip(dev->fd, pipe->crtc->crtc->crtc_id,
+ ret = drmModePageFlip(dev->fd, pipe->crtc_id,
other_fb_id, DRM_MODE_PAGE_FLIP_EVENT,
pipe);
if (ret) {
@@ -1650,7 +1843,6 @@ static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned
err_rmfb:
drmModeRmFB(dev->fd, other_fb_id);
-err:
bo_destroy(other_bo);
}
@@ -1695,6 +1887,8 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
return -1;
/* Parse the remaining parameters. */
+ if (!endp)
+ return -1;
if (*endp == '@') {
arg = endp + 1;
pipe->crtc_id = strtoul(arg, &endp, 10);
@@ -1713,7 +1907,7 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
pipe->mode_str[len] = '\0';
if (*p == '-') {
- pipe->vrefresh = strtoul(p + 1, &endp, 10);
+ pipe->vrefresh = strtof(p + 1, &endp);
p = endp;
}
@@ -1811,7 +2005,7 @@ static void parse_fill_patterns(char *arg)
static void usage(char *name)
{
- fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
+ fprintf(stderr, "usage: %s [-acDdefMPpsCvrw]\n", name);
fprintf(stderr, "\n Query options:\n\n");
fprintf(stderr, "\t-c\tlist connectors\n");
@@ -1821,9 +2015,10 @@ static void usage(char *name)
fprintf(stderr, "\n Test options:\n\n");
fprintf(stderr, "\t-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n");
- fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]\tset a mode\n");
+ fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>]\tset a mode\n");
fprintf(stderr, "\t-C\ttest hw cursor\n");
fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
+ fprintf(stderr, "\t-r\tset the preferred mode for all connectors\n");
fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
fprintf(stderr, "\t-a \tuse atomic API\n");
fprintf(stderr, "\t-F pattern1,pattern2\tspecify fill patterns\n");
@@ -1837,60 +2032,7 @@ static void usage(char *name)
exit(0);
}
-static int page_flipping_supported(void)
-{
- /*FIXME: generic ioctl needed? */
- return 1;
-#if 0
- int ret, value;
- struct drm_i915_getparam gp;
-
- gp.param = I915_PARAM_HAS_PAGEFLIPPING;
- gp.value = &value;
-
- ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
- if (ret) {
- fprintf(stderr, "drm_i915_getparam: %m\n");
- return 0;
- }
-
- return *gp.value;
-#endif
-}
-
-static int cursor_supported(void)
-{
- /*FIXME: generic ioctl needed? */
- return 1;
-}
-
-static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
-{
- drmModeConnector *connector;
- unsigned int i;
- uint32_t id;
- char *endp;
-
- for (i = 0; i < pipe->num_cons; i++) {
- id = strtoul(pipe->cons[i], &endp, 10);
- if (endp == pipe->cons[i]) {
- connector = get_connector_by_name(dev, pipe->cons[i]);
- if (!connector) {
- fprintf(stderr, "no connector named '%s'\n",
- pipe->cons[i]);
- return -ENODEV;
- }
-
- id = connector->connector_id;
- }
-
- pipe->con_ids[i] = id;
- }
-
- return 0;
-}
-
-static char optstr[] = "acdD:efF:M:P:ps:Cvw:";
+static char optstr[] = "acdD:efF:M:P:ps:Cvrw:";
int main(int argc, char **argv)
{
@@ -1901,6 +2043,7 @@ int main(int argc, char **argv)
int drop_master = 0;
int test_vsync = 0;
int test_cursor = 0;
+ int set_preferred = 0;
int use_atomic = 0;
char *device = NULL;
char *module = NULL;
@@ -1922,12 +2065,15 @@ int main(int argc, char **argv)
switch (c) {
case 'a':
use_atomic = 1;
+ /* Preserve the default behaviour of dumping all information. */
+ args--;
break;
case 'c':
connectors = 1;
break;
case 'D':
device = optarg;
+ /* Preserve the default behaviour of dumping all information. */
args--;
break;
case 'd':
@@ -1985,6 +2131,9 @@ int main(int argc, char **argv)
case 'v':
test_vsync = 1;
break;
+ case 'r':
+ set_preferred = 1;
+ break;
case 'w':
prop_args = realloc(prop_args,
(prop_count + 1) * sizeof *prop_args);
@@ -2005,51 +2154,45 @@ int main(int argc, char **argv)
}
}
- if (!args || (args == 1 && use_atomic))
+ /* Dump all the details when no* arguments are provided. */
+ if (!args)
encoders = connectors = crtcs = planes = framebuffers = 1;
- dev.fd = util_open(device, module);
- if (dev.fd < 0)
- return -1;
-
- ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1);
- if (ret && use_atomic) {
- fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno));
- drmClose(dev.fd);
+ if (test_vsync && !count) {
+ fprintf(stderr, "page flipping requires at least one -s option.\n");
return -1;
}
-
- dev.use_atomic = use_atomic;
-
- if (test_vsync && !page_flipping_supported()) {
- fprintf(stderr, "page flipping not supported by drm.\n");
+ if (set_preferred && count) {
+ fprintf(stderr, "cannot use -r (preferred) when -s (mode) is set\n");
return -1;
}
- if (test_vsync && !count) {
- fprintf(stderr, "page flipping requires at least one -s option.\n");
+ if (set_preferred && plane_count) {
+ fprintf(stderr, "cannot use -r (preferred) when -P (plane) is set\n");
return -1;
}
- if (test_cursor && !cursor_supported()) {
- fprintf(stderr, "hw cursor not supported by drm.\n");
+ dev.fd = util_open(device, module);
+ if (dev.fd < 0)
return -1;
+
+ if (use_atomic) {
+ ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1);
+ if (ret) {
+ fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno));
+ drmClose(dev.fd);
+ return -1;
+ }
}
+ dev.use_atomic = use_atomic;
+
dev.resources = get_resources(&dev);
if (!dev.resources) {
drmClose(dev.fd);
return 1;
}
- for (i = 0; i < count; i++) {
- if (pipe_resolve_connectors(&dev, &pipe_args[i]) < 0) {
- free_resources(dev.resources);
- drmClose(dev.fd);
- return 1;
- }
- }
-
#define dump_resource(dev, res) if (res) dump_##res(dev)
dump_resource(&dev, encoders);
@@ -2064,7 +2207,7 @@ int main(int argc, char **argv)
if (dev.use_atomic) {
dev.req = drmModeAtomicAlloc();
- if (count && plane_count) {
+ if (set_preferred || (count && plane_count)) {
uint64_t cap = 0;
ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap);
@@ -2073,8 +2216,11 @@ int main(int argc, char **argv)
return 1;
}
- atomic_set_mode(&dev, pipe_args, count);
- atomic_set_planes(&dev, plane_args, plane_count, false);
+ if (set_preferred || count)
+ set_mode(&dev, pipe_args, count);
+
+ if (plane_count)
+ atomic_set_planes(&dev, plane_args, plane_count, false);
ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
if (ret) {
@@ -2082,33 +2228,8 @@ int main(int argc, char **argv)
return 1;
}
- gettimeofday(&pipe_args->start, NULL);
- pipe_args->swap_count = 0;
-
- while (test_vsync) {
- drmModeAtomicFree(dev.req);
- dev.req = drmModeAtomicAlloc();
- atomic_set_planes(&dev, plane_args, plane_count, true);
-
- ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
- if (ret) {
- fprintf(stderr, "Atomic Commit failed [2]\n");
- return 1;
- }
-
- pipe_args->swap_count++;
- if (pipe_args->swap_count == 60) {
- struct timeval end;
- double t;
-
- gettimeofday(&end, NULL);
- t = end.tv_sec + end.tv_usec * 1e-6 -
- (pipe_args->start.tv_sec + pipe_args->start.tv_usec * 1e-6);
- fprintf(stderr, "freq: %.02fHz\n", pipe_args->swap_count / t);
- pipe_args->swap_count = 0;
- pipe_args->start = end;
- }
- }
+ if (test_vsync)
+ atomic_test_page_flip(&dev, pipe_args, plane_args, plane_count);
if (drop_master)
drmDropMaster(dev.fd);
@@ -2118,20 +2239,24 @@ int main(int argc, char **argv)
drmModeAtomicFree(dev.req);
dev.req = drmModeAtomicAlloc();
- atomic_clear_mode(&dev, pipe_args, count);
- atomic_clear_planes(&dev, plane_args, plane_count);
+ /* XXX: properly teardown the preferred mode/plane state */
+ if (plane_count)
+ atomic_clear_planes(&dev, plane_args, plane_count);
+
+ if (count)
+ atomic_clear_mode(&dev, pipe_args, count);
+
ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
- if (ret) {
+ if (ret)
fprintf(stderr, "Atomic Commit failed\n");
- return 1;
- }
- atomic_clear_FB(&dev, plane_args, plane_count);
+ if (plane_count)
+ atomic_clear_FB(&dev, plane_args, plane_count);
}
drmModeAtomicFree(dev.req);
} else {
- if (count || plane_count) {
+ if (set_preferred || count || plane_count) {
uint64_t cap = 0;
ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap);
@@ -2140,7 +2265,7 @@ int main(int argc, char **argv)
return 1;
}
- if (count)
+ if (set_preferred || count)
set_mode(&dev, pipe_args, count);
if (plane_count)
@@ -2163,12 +2288,13 @@ int main(int argc, char **argv)
if (plane_count)
clear_planes(&dev, plane_args, plane_count);
- if (count)
+ if (set_preferred || count)
clear_mode(&dev);
}
}
free_resources(dev.resources);
+ drmClose(dev.fd);
return 0;
}
diff --git a/tests/nouveau/Makefile.am b/tests/nouveau/Makefile.am
deleted file mode 100644
index 554f43ec..00000000
--- a/tests/nouveau/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-AM_CFLAGS = \
- -pthread \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/nouveau \
- -I$(top_srcdir)
-
-LDADD = \
- ../../nouveau/libdrm_nouveau.la \
- ../../libdrm.la \
- -ldl
-
-TESTS = threaded
-
-check_PROGRAMS = $(TESTS)
-
diff --git a/tests/nouveau/threaded.c b/tests/nouveau/threaded.c
index 3669bcd3..ddbac74e 100644
--- a/tests/nouveau/threaded.c
+++ b/tests/nouveau/threaded.c
@@ -36,7 +36,11 @@ static int failed;
static int import_fd;
+#if defined(__GLIBC__) || defined(__FreeBSD__)
int ioctl(int fd, unsigned long request, ...)
+#else
+int ioctl(int fd, int request, ...)
+#endif
{
va_list va;
int ret;
diff --git a/tests/proptest/Android.bp b/tests/proptest/Android.bp
index 28c87e91..e13d060b 100644
--- a/tests/proptest/Android.bp
+++ b/tests/proptest/Android.bp
@@ -1,3 +1,12 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
cc_test {
name: "proptest",
defaults: ["libdrm_defaults"],
diff --git a/tests/proptest/Makefile.am b/tests/proptest/Makefile.am
deleted file mode 100644
index 33b8705b..00000000
--- a/tests/proptest/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-include Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS)\
- -fvisibility=hidden \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/tests \
- -I$(top_srcdir)
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- proptest
-else
-noinst_PROGRAMS = \
- proptest
-endif
-
-proptest_SOURCES = $(PROPTEST_FILES)
-
-proptest_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/tests/util/libutil.la
diff --git a/tests/radeon/Makefile.am b/tests/radeon/Makefile.am
deleted file mode 100644
index 3d173e31..00000000
--- a/tests/radeon/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-AM_CFLAGS = \
- $(WARN_CFLAGS)\
- -fvisibility=hidden \
- -I $(top_srcdir)/include/drm \
- -I $(top_srcdir)
-
-LDADD = $(top_builddir)/libdrm.la
-
-noinst_PROGRAMS = \
- radeon_ttm
-
-radeon_ttm_SOURCES = \
- rbo.c \
- rbo.h \
- radeon_ttm.c
diff --git a/tests/random.c b/tests/random.c
deleted file mode 100644
index 13d4c805..00000000
--- a/tests/random.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation
- * Created: Mon Apr 19 08:28:13 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * 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
- * PRECISION INSIGHT 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.
- *
- * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
- *
- * DESCRIPTION
- *
- * This file contains a simple, straightforward implementation of the Park
- * & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer
- * multiplicative linear congruential generator (MLCG) with a period of
- * 2^31-1.
- *
- * This implementation is intended to provide a reliable, portable PRNG
- * that is suitable for testing a hash table implementation and for
- * implementing skip lists.
- *
- * FUTURE ENHANCEMENTS
- *
- * If initial seeds are not selected randomly, two instances of the PRNG
- * can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique
- * that can eliminate this problem.
- *
- * If PRNGs are used for simulation, the period of the current
- * implementation may be too short. [LE88] discusses methods of combining
- * MLCGs to produce much longer periods, and suggests some alternative
- * values for A and M. [LE90 and Sch92] also provide information on
- * long-period PRNGs.
- *
- * REFERENCES
- *
- * [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2:
- * Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981.
- *
- * [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number
- * Generators". CACM 31(6), June 1988, pp. 742-774.
- *
- * [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10,
- * October 1990, pp. 85-97.
- *
- * [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators:
- * Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201.
- *
- * [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit
- * CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40.
- *
- * [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In
- * "Technical Correspondence: Remarks on Choosing and Implementing Random
- * Number Generators". CACM 36(7), July 1993, pp. 105-110.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "xf86drm.h"
-#include "xf86drmRandom.h"
-
-static void check_period(unsigned long seed)
-{
- unsigned long count = 0;
- unsigned long initial;
- void *state;
-
- state = drmRandomCreate(seed);
- initial = drmRandom(state);
- ++count;
- while (initial != drmRandom(state)) {
- if (!++count) break;
- }
- printf("With seed of %10lu, period = %10lu (0x%08lx)\n",
- seed, count, count);
- drmRandomDestroy(state);
-}
-
-int main(void)
-{
- RandomState *state;
- int i;
- int ret;
- unsigned long rand;
-
- state = drmRandomCreate(1);
- for (i = 0; i < 10000; i++) {
- rand = drmRandom(state);
- }
- ret = rand != state->check;
- printf("After 10000 iterations: %lu (%lu expected): %s\n",
- rand, state->check,
- ret ? "*INCORRECT*" : "CORRECT");
- drmRandomDestroy(state);
-
- printf("Checking periods...\n");
- check_period(1);
- check_period(2);
- check_period(31415926);
-
- return ret;
-}
diff --git a/tests/tegra/Makefile.am b/tests/tegra/Makefile.am
deleted file mode 100644
index b462a30c..00000000
--- a/tests/tegra/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-AM_CPPFLAGS = \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/tegra \
- -I$(top_srcdir)
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden
-
-LDADD = \
- ../../tegra/libdrm_tegra.la \
- ../../libdrm.la
-
-noinst_PROGRAMS = \
- openclose
diff --git a/tests/util/Android.bp b/tests/util/Android.bp
index 36d18206..0322c2ac 100644
--- a/tests/util/Android.bp
+++ b/tests/util/Android.bp
@@ -21,6 +21,15 @@
// IN THE SOFTWARE.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_libdrm_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-MIT
+ default_applicable_licenses: ["external_libdrm_license"],
+}
+
build = ["Android.sources.bp"]
cc_library_static {
diff --git a/tests/util/Makefile.am b/tests/util/Makefile.am
deleted file mode 100644
index f8e0b171..00000000
--- a/tests/util/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-include Makefile.sources
-
-noinst_LTLIBRARIES = \
- libutil.la
-
-libutil_la_CPPFLAGS = \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)
-
-libutil_la_CFLAGS = \
- $(CAIRO_CFLAGS)
-
-libutil_la_SOURCES = $(UTIL_FILES)
diff --git a/tests/util/kms.c b/tests/util/kms.c
index dd1bbee3..39a93866 100644
--- a/tests/util/kms.c
+++ b/tests/util/kms.c
@@ -147,6 +147,9 @@ static const char * const modules[] = {
"stm",
"sun4i-drm",
"armada-drm",
+ "komeda",
+ "imx-dcss",
+ "mxsfb-drm",
};
int util_open(const char *device, const char *module)
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index 42a0e5c7..158c0b16 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -643,7 +643,7 @@ void util_smpte_c8_gamma(unsigned size, struct drm_color_lut *lut)
printf("Error: gamma too small: %d < %d\n", size, 7 + 7 + 8);
return;
}
- memset(lut, size * sizeof(struct drm_color_lut), 0);
+ memset(lut, 0, size * sizeof(struct drm_color_lut));
#define FILL_COLOR(idx, r, g, b) \
lut[idx].red = (r) << 8; \
@@ -985,7 +985,6 @@ static void fill_tiles_rgb16fp(const struct util_format_info *info, void *mem,
unsigned int stride)
{
const struct util_rgb_info *rgb = &info->rgb;
- void *mem_base = mem;
unsigned int x, y;
/* TODO: Give this actual fp16 precision */
@@ -1113,7 +1112,7 @@ static void fill_gradient_rgb32(const struct util_rgb_info *rgb,
unsigned int width, unsigned int height,
unsigned int stride)
{
- int i, j;
+ unsigned int i, j;
for (i = 0; i < height / 2; i++) {
uint32_t *row = mem;
@@ -1141,7 +1140,7 @@ static void fill_gradient_rgb16fp(const struct util_rgb_info *rgb,
unsigned int width, unsigned int height,
unsigned int stride)
{
- int i, j;
+ unsigned int i, j;
for (i = 0; i < height / 2; i++) {
uint64_t *row = mem;
diff --git a/tests/vbltest/Makefile.am b/tests/vbltest/Makefile.am
deleted file mode 100644
index b6cd7a4d..00000000
--- a/tests/vbltest/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-AM_CFLAGS = \
- $(WARN_CFLAGS)\
- -fvisibility=hidden \
- -I$(top_srcdir)/include/drm \
- -I$(top_srcdir)/tests \
- -I$(top_srcdir)
-
-if HAVE_INSTALL_TESTS
-bin_PROGRAMS = \
- vbltest
-else
-noinst_PROGRAMS = \
- vbltest
-endif
-
-vbltest_SOURCES = \
- vbltest.c
-vbltest_LDADD = \
- $(top_builddir)/libdrm.la \
- $(top_builddir)/tests/util/libutil.la
diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c
index 48708d20..1c2b519e 100644
--- a/tests/vbltest/vbltest.c
+++ b/tests/vbltest/vbltest.c
@@ -33,7 +33,7 @@
#include <errno.h>
#include <poll.h>
#include <sys/time.h>
-#ifdef HAVE_SYS_SELECT_H
+#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
diff --git a/vc4/Makefile.am b/vc4/Makefile.am
deleted file mode 100644
index 5f82d04e..00000000
--- a/vc4/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright © 2016 Broadcom
-#
-# 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 AUTHORS OR COPYRIGHT HOLDERS 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 Makefile.sources
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -fvisibility=hidden \
- -I$(top_srcdir) \
- $(PTHREADSTUBS_CFLAGS) \
- $(VALGRIND_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_vc4includedir = ${includedir}/libdrm
-libdrm_vc4include_HEADERS = $(LIBDRM_VC4_H_FILES)
-
-pkgconfig_DATA = libdrm_vc4.pc
diff --git a/xf86atomic.h b/xf86atomic.h
index 2d733bd5..efa47a77 100644
--- a/xf86atomic.h
+++ b/xf86atomic.h
@@ -54,6 +54,7 @@ typedef struct {
#endif
#if HAVE_LIB_ATOMIC_OPS
+#define AO_REQUIRE_CAS
#include <atomic_ops.h>
#define HAS_ATOMIC_OPS 1
diff --git a/xf86drm.c b/xf86drm.c
index 155c5a8a..edfeb347 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -57,8 +57,16 @@
#ifdef MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#endif
+#if HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
#include <math.h>
+#if defined(__FreeBSD__)
+#include <sys/param.h>
+#include <sys/pciio.h>
+#endif
+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
/* Not all systems have MAP_FAILED defined */
@@ -71,17 +79,7 @@
#include "util_math.h"
-#ifdef __OpenBSD__
-#define DRM_PRIMARY_MINOR_NAME "drm"
-#define DRM_CONTROL_MINOR_NAME "drmC"
-#define DRM_RENDER_MINOR_NAME "drmR"
-#else
-#define DRM_PRIMARY_MINOR_NAME "card"
-#define DRM_CONTROL_MINOR_NAME "controlD"
-#define DRM_RENDER_MINOR_NAME "renderD"
-#endif
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+#ifdef __DragonFly__
#define DRM_MAJOR 145
#endif
@@ -123,6 +121,25 @@ struct drm_pciinfo {
static drmServerInfoPtr drm_server_info;
+static bool drmNodeIsDRM(int maj, int min);
+static char *drmGetMinorNameForFD(int fd, int type);
+
+static unsigned log2_int(unsigned x)
+{
+ unsigned l;
+
+ if (x < 2) {
+ return 0;
+ }
+ for (l = 2; ; l++) {
+ if ((unsigned)(1 << l) > x) {
+ return l - 1;
+ }
+ }
+ return 0;
+}
+
+
drm_public void drmSetServerInfo(drmServerInfoPtr info)
{
drm_server_info = info;
@@ -310,6 +327,19 @@ static int chown_check_return(const char *path, uid_t owner, gid_t group)
}
#endif
+static const char *drmGetDeviceName(int type)
+{
+ switch (type) {
+ case DRM_NODE_PRIMARY:
+ return DRM_DEV_NAME;
+ case DRM_NODE_CONTROL:
+ return DRM_CONTROL_DEV_NAME;
+ case DRM_NODE_RENDER:
+ return DRM_RENDER_DEV_NAME;
+ }
+ return NULL;
+}
+
/**
* Open the DRM device, creating it if necessary.
*
@@ -326,8 +356,8 @@ static int chown_check_return(const char *path, uid_t owner, gid_t group)
static int drmOpenDevice(dev_t dev, int minor, int type)
{
stat_t st;
- const char *dev_name;
- char buf[64];
+ const char *dev_name = drmGetDeviceName(type);
+ char buf[DRM_NODE_NAME_MAX];
int fd;
mode_t devmode = DRM_DEV_MODE, serv_mode;
gid_t serv_group;
@@ -337,19 +367,8 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
gid_t group = DRM_DEV_GID;
#endif
- switch (type) {
- case DRM_NODE_PRIMARY:
- dev_name = DRM_DEV_NAME;
- break;
- case DRM_NODE_CONTROL:
- dev_name = DRM_CONTROL_DEV_NAME;
- break;
- case DRM_NODE_RENDER:
- dev_name = DRM_RENDER_DEV_NAME;
- break;
- default:
+ if (!dev_name)
return -EINVAL;
- };
sprintf(buf, dev_name, DRM_DIR_NAME, minor);
drmMsg("drmOpenDevice: node name is %s\n", buf);
@@ -455,25 +474,14 @@ wait_for_udev:
static int drmOpenMinor(int minor, int create, int type)
{
int fd;
- char buf[64];
- const char *dev_name;
+ char buf[DRM_NODE_NAME_MAX];
+ const char *dev_name = drmGetDeviceName(type);
if (create)
return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
- switch (type) {
- case DRM_NODE_PRIMARY:
- dev_name = DRM_DEV_NAME;
- break;
- case DRM_NODE_CONTROL:
- dev_name = DRM_CONTROL_DEV_NAME;
- break;
- case DRM_NODE_RENDER:
- dev_name = DRM_RENDER_DEV_NAME;
- break;
- default:
+ if (!dev_name)
return -EINVAL;
- };
sprintf(buf, dev_name, DRM_DIR_NAME, minor);
if ((fd = open(buf, O_RDWR | O_CLOEXEC, 0)) >= 0)
@@ -530,8 +538,28 @@ static int drmGetMinorBase(int type)
};
}
-static int drmGetMinorType(int minor)
+static int drmGetMinorType(int major, int minor)
{
+#ifdef __FreeBSD__
+ char name[SPECNAMELEN];
+ int id;
+
+ if (!devname_r(makedev(major, minor), S_IFCHR, name, sizeof(name)))
+ return -1;
+
+ if (sscanf(name, "drm/%d", &id) != 1) {
+ // If not in /dev/drm/ we have the type in the name
+ if (sscanf(name, "dri/card%d\n", &id) >= 1)
+ return DRM_NODE_PRIMARY;
+ else if (sscanf(name, "dri/control%d\n", &id) >= 1)
+ return DRM_NODE_CONTROL;
+ else if (sscanf(name, "dri/renderD%d\n", &id) >= 1)
+ return DRM_NODE_RENDER;
+ return -1;
+ }
+
+ minor = id;
+#endif
int type = minor >> 6;
if (minor < 0)
@@ -684,7 +712,7 @@ static int drmOpenByName(const char *name, int type)
int retcode;
sprintf(proc_name, "/proc/dri/%d/name", i);
- if ((fd = open(proc_name, 0, 0)) >= 0) {
+ if ((fd = open(proc_name, O_RDONLY, 0)) >= 0) {
retcode = read(fd, buf, sizeof(buf)-1);
close(fd);
if (retcode) {
@@ -1323,7 +1351,12 @@ drm_public drmBufInfoPtr drmGetBufInfo(int fd)
retval = drmMalloc(sizeof(*retval));
retval->count = info.count;
- retval->list = drmMalloc(info.count * sizeof(*retval->list));
+ if (!(retval->list = drmMalloc(info.count * sizeof(*retval->list)))) {
+ drmFree(retval);
+ drmFree(info.list);
+ return NULL;
+ }
+
for (i = 0; i < info.count; i++) {
retval->list[i].count = info.list[i].count;
retval->list[i].size = info.list[i].size;
@@ -2763,6 +2796,19 @@ drm_public int drmIsMaster(int fd)
drm_public char *drmGetDeviceNameFromFd(int fd)
{
+#ifdef __FreeBSD__
+ struct stat sbuf;
+ int maj, min;
+ int nodetype;
+
+ if (fstat(fd, &sbuf))
+ return NULL;
+
+ maj = major(sbuf.st_rdev);
+ min = minor(sbuf.st_rdev);
+ nodetype = drmGetMinorType(maj, min);
+ return drmGetMinorNameForFD(fd, nodetype);
+#else
char name[128];
struct stat sbuf;
dev_t d;
@@ -2785,6 +2831,7 @@ drm_public char *drmGetDeviceNameFromFd(int fd)
return NULL;
return strdup(name);
+#endif
}
static bool drmNodeIsDRM(int maj, int min)
@@ -2796,6 +2843,16 @@ static bool drmNodeIsDRM(int maj, int min)
snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/drm",
maj, min);
return stat(path, &sbuf) == 0;
+#elif defined(__FreeBSD__)
+ char name[SPECNAMELEN];
+
+ if (!devname_r(makedev(maj, min), S_IFCHR, name, sizeof(name)))
+ return 0;
+ /* Handle drm/ and dri/ as both are present in different FreeBSD version
+ * FreeBSD on amd64/i386/powerpc external kernel modules create node in
+ * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates
+ * only device nodes in /dev/dri/ */
+ return (!strncmp(name, "drm/", 4) || !strncmp(name, "dri/", 4));
#else
return maj == DRM_MAJOR;
#endif
@@ -2817,7 +2874,7 @@ drm_public int drmGetNodeTypeFromFd(int fd)
return -1;
}
- type = drmGetMinorType(min);
+ type = drmGetMinorType(maj, min);
if (type == -1)
errno = ENODEV;
return type;
@@ -2899,12 +2956,55 @@ static char *drmGetMinorNameForFD(int fd, int type)
closedir(sysdir);
return NULL;
+#elif defined(__FreeBSD__)
+ struct stat sbuf;
+ char dname[SPECNAMELEN];
+ const char *mname;
+ char name[SPECNAMELEN];
+ int id, maj, min, nodetype, i;
+
+ if (fstat(fd, &sbuf))
+ return NULL;
+
+ maj = major(sbuf.st_rdev);
+ min = minor(sbuf.st_rdev);
+
+ if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
+ return NULL;
+
+ if (!devname_r(sbuf.st_rdev, S_IFCHR, dname, sizeof(dname)))
+ return NULL;
+
+ /* Handle both /dev/drm and /dev/dri
+ * FreeBSD on amd64/i386/powerpc external kernel modules create node in
+ * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates
+ * only device nodes in /dev/dri/ */
+
+ /* Get the node type represented by fd so we can deduce the target name */
+ nodetype = drmGetMinorType(maj, min);
+ if (nodetype == -1)
+ return (NULL);
+ mname = drmGetMinorName(type);
+
+ for (i = 0; i < SPECNAMELEN; i++) {
+ if (isalpha(dname[i]) == 0 && dname[i] != '/')
+ break;
+ }
+ if (dname[i] == '\0')
+ return (NULL);
+
+ id = (int)strtol(&dname[i], NULL, 10);
+ id -= drmGetMinorBase(nodetype);
+ snprintf(name, sizeof(name), DRM_DIR_NAME "/%s%d", mname,
+ id + drmGetMinorBase(type));
+
+ return strdup(name);
#else
struct stat sbuf;
char buf[PATH_MAX + 1];
- const char *dev_name;
+ const char *dev_name = drmGetDeviceName(type);
unsigned int maj, min;
- int n, base;
+ int n;
if (fstat(fd, &sbuf))
return NULL;
@@ -2915,25 +3015,10 @@ static char *drmGetMinorNameForFD(int fd, int type)
if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return NULL;
- switch (type) {
- case DRM_NODE_PRIMARY:
- dev_name = DRM_DEV_NAME;
- break;
- case DRM_NODE_CONTROL:
- dev_name = DRM_CONTROL_DEV_NAME;
- break;
- case DRM_NODE_RENDER:
- dev_name = DRM_RENDER_DEV_NAME;
- break;
- default:
- return NULL;
- };
-
- base = drmGetMinorBase(type);
- if (base < 0)
+ if (!dev_name)
return NULL;
- n = snprintf(buf, sizeof(buf), dev_name, DRM_DIR_NAME, min - base);
+ n = snprintf(buf, sizeof(buf), dev_name, DRM_DIR_NAME, min);
if (n == -1 || n >= sizeof(buf))
return NULL;
@@ -3043,17 +3128,20 @@ static int drmParseSubsystemType(int maj, int min)
int subsystem_type;
snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
- if (!realpath(path, real_path))
- return -errno;
- snprintf(path, sizeof(path), "%s", real_path);
subsystem_type = get_subsystem_type(path);
+ /* Try to get the parent (underlying) device type */
if (subsystem_type == DRM_BUS_VIRTIO) {
+ /* Assume virtio-pci on error */
+ if (!realpath(path, real_path))
+ return DRM_BUS_VIRTIO;
strncat(path, "/..", PATH_MAX);
subsystem_type = get_subsystem_type(path);
- }
+ if (subsystem_type < 0)
+ return DRM_BUS_VIRTIO;
+ }
return subsystem_type;
-#elif defined(__OpenBSD__) || defined(__DragonFly__)
+#elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__)
return DRM_BUS_PCI;
#else
#warning "Missing implementation of drmParseSubsystemType"
@@ -3061,6 +3149,7 @@ static int drmParseSubsystemType(int maj, int min)
#endif
}
+#ifdef __linux__
static void
get_pci_path(int maj, int min, char *pci_path)
{
@@ -3076,6 +3165,67 @@ get_pci_path(int maj, int min, char *pci_path)
if (term && strncmp(term, "/virtio", 7) == 0)
*term = 0;
}
+#endif
+
+#ifdef __FreeBSD__
+static int get_sysctl_pci_bus_info(int maj, int min, drmPciBusInfoPtr info)
+{
+ char dname[SPECNAMELEN];
+ char sysctl_name[16];
+ char sysctl_val[256];
+ size_t sysctl_len;
+ int id, type, nelem;
+ unsigned int rdev, majmin, domain, bus, dev, func;
+
+ rdev = makedev(maj, min);
+ if (!devname_r(rdev, S_IFCHR, dname, sizeof(dname)))
+ return -EINVAL;
+
+ if (sscanf(dname, "drm/%d\n", &id) != 1)
+ return -EINVAL;
+ type = drmGetMinorType(maj, min);
+ if (type == -1)
+ return -EINVAL;
+
+ /* BUG: This above section is iffy, since it mandates that a driver will
+ * create both card and render node.
+ * If it does not, the next DRM device will create card#X and
+ * renderD#(128+X)-1.
+ * This is a possibility in FreeBSD but for now there is no good way for
+ * obtaining the info.
+ */
+ switch (type) {
+ case DRM_NODE_PRIMARY:
+ break;
+ case DRM_NODE_CONTROL:
+ id -= 64;
+ break;
+ case DRM_NODE_RENDER:
+ id -= 128;
+ break;
+ }
+ if (id < 0)
+ return -EINVAL;
+
+ if (snprintf(sysctl_name, sizeof(sysctl_name), "hw.dri.%d.busid", id) <= 0)
+ return -EINVAL;
+ sysctl_len = sizeof(sysctl_val);
+ if (sysctlbyname(sysctl_name, sysctl_val, &sysctl_len, NULL, 0))
+ return -EINVAL;
+
+ #define bus_fmt "pci:%04x:%02x:%02x.%u"
+
+ nelem = sscanf(sysctl_val, bus_fmt, &domain, &bus, &dev, &func);
+ if (nelem != 4)
+ return -EINVAL;
+ info->domain = domain;
+ info->bus = bus;
+ info->dev = dev;
+ info->func = func;
+
+ return 0;
+}
+#endif
static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
{
@@ -3106,7 +3256,7 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
struct drm_pciinfo pinfo;
int fd, type;
- type = drmGetMinorType(min);
+ type = drmGetMinorType(maj, min);
if (type == -1)
return -ENODEV;
@@ -3126,6 +3276,8 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
info->func = pinfo.func;
return 0;
+#elif defined(__FreeBSD__)
+ return get_sysctl_pci_bus_info(maj, min, info);
#else
#warning "Missing implementation of drmParsePciBusInfo"
return -EINVAL;
@@ -3162,10 +3314,6 @@ drm_public int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b)
static int drmGetNodeType(const char *name)
{
- if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
- sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
- return DRM_NODE_PRIMARY;
-
if (strncmp(name, DRM_CONTROL_MINOR_NAME,
sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0)
return DRM_NODE_CONTROL;
@@ -3174,6 +3322,10 @@ static int drmGetNodeType(const char *name)
sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
return DRM_NODE_RENDER;
+ if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
+ sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
+ return DRM_NODE_PRIMARY;
+
return -EINVAL;
}
@@ -3272,7 +3424,7 @@ static int drmParsePciDeviceInfo(int maj, int min,
struct drm_pciinfo pinfo;
int fd, type;
- type = drmGetMinorType(min);
+ type = drmGetMinorType(maj, min);
if (type == -1)
return -ENODEV;
@@ -3293,6 +3445,48 @@ static int drmParsePciDeviceInfo(int maj, int min,
device->subdevice_id = pinfo.subdevice_id;
return 0;
+#elif defined(__FreeBSD__)
+ drmPciBusInfo info;
+ struct pci_conf_io pc;
+ struct pci_match_conf patterns[1];
+ struct pci_conf results[1];
+ int fd, error;
+
+ if (get_sysctl_pci_bus_info(maj, min, &info) != 0)
+ return -EINVAL;
+
+ fd = open("/dev/pci", O_RDONLY, 0);
+ if (fd < 0)
+ return -errno;
+
+ bzero(&patterns, sizeof(patterns));
+ patterns[0].pc_sel.pc_domain = info.domain;
+ patterns[0].pc_sel.pc_bus = info.bus;
+ patterns[0].pc_sel.pc_dev = info.dev;
+ patterns[0].pc_sel.pc_func = info.func;
+ patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN | PCI_GETCONF_MATCH_BUS
+ | PCI_GETCONF_MATCH_DEV | PCI_GETCONF_MATCH_FUNC;
+ bzero(&pc, sizeof(struct pci_conf_io));
+ pc.num_patterns = 1;
+ pc.pat_buf_len = sizeof(patterns);
+ pc.patterns = patterns;
+ pc.match_buf_len = sizeof(results);
+ pc.matches = results;
+
+ if (ioctl(fd, PCIOCGETCONF, &pc) || pc.status == PCI_GETCONF_ERROR) {
+ error = errno;
+ close(fd);
+ return -error;
+ }
+ close(fd);
+
+ device->vendor_id = results[0].pc_vendor;
+ device->device_id = results[0].pc_device;
+ device->subvendor_id = results[0].pc_subvendor;
+ device->subdevice_id = results[0].pc_subdevice;
+ device->revision_id = results[0].pc_revid;
+
+ return 0;
#else
#warning "Missing implementation of drmParsePciDeviceInfo"
return -EINVAL;
@@ -3442,6 +3636,46 @@ free_device:
return ret;
}
+#ifdef __linux__
+static int drm_usb_dev_path(int maj, int min, char *path, size_t len)
+{
+ char *value, *tmp_path, *slash;
+
+ snprintf(path, len, "/sys/dev/char/%d:%d/device", maj, min);
+
+ value = sysfs_uevent_get(path, "DEVTYPE");
+ if (!value)
+ return -ENOENT;
+
+ if (strcmp(value, "usb_device") == 0)
+ return 0;
+ if (strcmp(value, "usb_interface") != 0)
+ return -ENOTSUP;
+
+ /* The parent of a usb_interface is a usb_device */
+
+ tmp_path = realpath(path, NULL);
+ if (!tmp_path)
+ return -errno;
+
+ slash = strrchr(tmp_path, '/');
+ if (!slash) {
+ free(tmp_path);
+ return -EINVAL;
+ }
+
+ *slash = '\0';
+
+ if (snprintf(path, len, "%s", tmp_path) >= (int)len) {
+ free(tmp_path);
+ return -EINVAL;
+ }
+
+ free(tmp_path);
+ return 0;
+}
+#endif
+
static int drmParseUsbBusInfo(int maj, int min, drmUsbBusInfoPtr info)
{
#ifdef __linux__
@@ -3449,7 +3683,9 @@ static int drmParseUsbBusInfo(int maj, int min, drmUsbBusInfoPtr info)
unsigned int bus, dev;
int ret;
- snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+ ret = drm_usb_dev_path(maj, min, path, sizeof(path));
+ if (ret < 0)
+ return ret;
value = sysfs_uevent_get(path, "BUSNUM");
if (!value)
@@ -3488,7 +3724,9 @@ static int drmParseUsbDeviceInfo(int maj, int min, drmUsbDeviceInfoPtr info)
unsigned int vendor, product;
int ret;
- snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+ ret = drm_usb_dev_path(maj, min, path, sizeof(path));
+ if (ret < 0)
+ return ret;
value = sysfs_uevent_get(path, "PRODUCT");
if (!value)
@@ -3754,6 +3992,7 @@ process_device(drmDevicePtr *device, const char *d_name,
switch (subsystem_type) {
case DRM_BUS_PCI:
+ case DRM_BUS_VIRTIO:
return drmProcessPciDevice(device, node, node_type, maj, min,
fetch_deviceinfo, flags);
case DRM_BUS_USB:
@@ -3783,7 +4022,7 @@ static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
for (j = i + 1; j < count; j++) {
if (drmDevicesEqual(local_devices[i], local_devices[j])) {
local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
- node_type = log2(local_devices[j]->available_nodes);
+ node_type = log2_int(local_devices[j]->available_nodes);
memcpy(local_devices[i]->nodes[node_type],
local_devices[j]->nodes[node_type], drmGetMaxNodeName());
drmFreeDevice(&local_devices[j]);
@@ -3847,7 +4086,7 @@ drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
char node[PATH_MAX + 1];
const char *dev_name;
int node_type, subsystem_type;
- int maj, min, n, ret, base;
+ int maj, min, n, ret;
if (fd == -1 || device == NULL)
return -EINVAL;
@@ -3861,29 +4100,15 @@ drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return -EINVAL;
- node_type = drmGetMinorType(min);
+ node_type = drmGetMinorType(maj, min);
if (node_type == -1)
return -ENODEV;
- switch (node_type) {
- case DRM_NODE_PRIMARY:
- dev_name = DRM_DEV_NAME;
- break;
- case DRM_NODE_CONTROL:
- dev_name = DRM_CONTROL_DEV_NAME;
- break;
- case DRM_NODE_RENDER:
- dev_name = DRM_RENDER_DEV_NAME;
- break;
- default:
- return -EINVAL;
- };
-
- base = drmGetMinorBase(node_type);
- if (base < 0)
+ dev_name = drmGetDeviceName(node_type);
+ if (!dev_name)
return -EINVAL;
- n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base);
+ n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
if (n == -1 || n >= PATH_MAX)
return -errno;
if (stat(node, &sbuf))
@@ -4052,6 +4277,10 @@ drm_public int drmGetDevices2(uint32_t flags, drmDevicePtr devices[],
}
closedir(sysdir);
+
+ if (devices != NULL)
+ return MIN2(device_count, max_devices);
+
return device_count;
}
@@ -4098,12 +4327,14 @@ drm_public char *drmGetDeviceNameFromFd2(int fd)
free(value);
return strdup(path);
+#elif defined(__FreeBSD__)
+ return drmGetDeviceNameFromFd(fd);
#else
struct stat sbuf;
char node[PATH_MAX + 1];
const char *dev_name;
int node_type;
- int maj, min, n, base;
+ int maj, min, n;
if (fstat(fd, &sbuf))
return NULL;
@@ -4114,29 +4345,15 @@ drm_public char *drmGetDeviceNameFromFd2(int fd)
if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
return NULL;
- node_type = drmGetMinorType(min);
+ node_type = drmGetMinorType(maj, min);
if (node_type == -1)
return NULL;
- switch (node_type) {
- case DRM_NODE_PRIMARY:
- dev_name = DRM_DEV_NAME;
- break;
- case DRM_NODE_CONTROL:
- dev_name = DRM_CONTROL_DEV_NAME;
- break;
- case DRM_NODE_RENDER:
- dev_name = DRM_RENDER_DEV_NAME;
- break;
- default:
- return NULL;
- };
-
- base = drmGetMinorBase(node_type);
- if (base < 0)
+ dev_name = drmGetDeviceName(node_type);
+ if (!dev_name)
return NULL;
- n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base);
+ n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
if (n == -1 || n >= PATH_MAX)
return NULL;
@@ -4334,6 +4551,21 @@ drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
return 0;
}
+drm_public int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
+ uint32_t handle_count, uint32_t flags)
+{
+ struct drm_syncobj_timeline_array args;
+
+ memclear(args);
+ args.handles = (uintptr_t)handles;
+ args.points = (uintptr_t)points;
+ args.count_handles = handle_count;
+ args.flags = flags;
+
+ return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
+}
+
+
drm_public int drmSyncobjTransfer(int fd,
uint32_t dst_handle, uint64_t dst_point,
uint32_t src_handle, uint64_t src_point,
diff --git a/xf86drm.h b/xf86drm.h
index 3fb1d1ca..9fc06ab8 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -78,17 +78,29 @@ extern "C" {
#ifdef __OpenBSD__
#define DRM_DIR_NAME "/dev"
-#define DRM_DEV_NAME "%s/drm%d"
-#define DRM_CONTROL_DEV_NAME "%s/drmC%d"
-#define DRM_RENDER_DEV_NAME "%s/drmR%d"
+#define DRM_PRIMARY_MINOR_NAME "drm"
+#define DRM_CONTROL_MINOR_NAME "drmC"
+#define DRM_RENDER_MINOR_NAME "drmR"
#else
#define DRM_DIR_NAME "/dev/dri"
-#define DRM_DEV_NAME "%s/card%d"
-#define DRM_CONTROL_DEV_NAME "%s/controlD%d"
-#define DRM_RENDER_DEV_NAME "%s/renderD%d"
+#define DRM_PRIMARY_MINOR_NAME "card"
+#define DRM_CONTROL_MINOR_NAME "controlD"
+#define DRM_RENDER_MINOR_NAME "renderD"
#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
#endif
+#define DRM_DEV_NAME "%s/" DRM_PRIMARY_MINOR_NAME "%d"
+#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d"
+#define DRM_RENDER_DEV_NAME "%s/" DRM_RENDER_MINOR_NAME "%d"
+
+#define DRM_NODE_NAME_MAX \
+ (sizeof(DRM_DIR_NAME) + 1 /* slash */ \
+ + MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), \
+ sizeof(DRM_CONTROL_MINOR_NAME), \
+ sizeof(DRM_RENDER_MINOR_NAME)) \
+ + sizeof("144") /* highest possible node number */ \
+ + 1) /* NULL-terminator */
+
#define DRM_ERR_NO_DEVICE (-1001)
#define DRM_ERR_NO_ACCESS (-1002)
#define DRM_ERR_NOT_ROOT (-1003)
@@ -469,6 +481,29 @@ do { register unsigned int __old __asm("o0"); \
: "cr0", "memory"); \
} while (0)
+# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+ || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) \
+ || defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__)
+ /* excluding ARMv4/ARMv5 and lower (lacking ldrex/strex support) */
+ #undef DRM_DEV_MODE
+ #define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
+
+ #define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ __asm__ __volatile__ ( \
+ "1: ldrex %0, [%1]\n" \
+ " teq %0, %2\n" \
+ " ite eq\n" \
+ " strexeq %0, %3, [%1]\n" \
+ " movne %0, #1\n" \
+ : "=&r" (__ret) \
+ : "r" (lock), "r" (old), "r" (new) \
+ : "cc","memory"); \
+ } while (0)
+
#endif /* architecture */
#endif /* __GNUC__ >= 2 */
@@ -778,6 +813,24 @@ extern char *drmGetDeviceNameFromFd(int fd);
extern char *drmGetDeviceNameFromFd2(int fd);
extern int drmGetNodeTypeFromFd(int fd);
+/* Convert between GEM handles and DMA-BUF file descriptors.
+ *
+ * Warning: since GEM handles are not reference-counted and are unique per
+ * DRM file description, the caller is expected to perform its own reference
+ * counting. drmPrimeFDToHandle is guaranteed to return the same handle for
+ * different FDs if they reference the same underlying buffer object. This
+ * could even be a buffer object originally created on the same DRM FD.
+ *
+ * When sharing a DRM FD with an API such as EGL or GBM, the caller must not
+ * use drmPrimeHandleToFD nor drmPrimeFDToHandle. A single user-space
+ * reference-counting implementation is necessary to avoid double-closing GEM
+ * handles.
+ *
+ * Two processes can't share the same DRM FD and both use it to create or
+ * import GEM handles, even when using a single user-space reference-counting
+ * implementation like GBM, because GBM doesn't share its state between
+ * processes.
+ */
extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);
extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle);
@@ -884,6 +937,8 @@ extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
uint32_t *first_signaled);
extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
uint32_t handle_count);
+extern int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
+ uint32_t handle_count, uint32_t flags);
extern int drmSyncobjTransfer(int fd,
uint32_t dst_handle, uint64_t dst_point,
uint32_t src_handle, uint64_t src_point,
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 207d7be9..c3920b91 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -33,16 +33,11 @@
*
*/
-/*
- * TODO the types we are after are defined in different headers on different
- * platforms find which headers to include to get uint32_t
- */
-
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/ioctl.h>
-#ifdef HAVE_SYS_SYSCTL_H
+#if HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#include <stdio.h>
@@ -151,6 +146,16 @@ drm_public void drmModeFreeEncoder(drmModeEncoderPtr ptr)
* ModeSetting functions.
*/
+drm_public int drmIsKMS(int fd)
+{
+ struct drm_mode_card_res res = {0};
+
+ if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res) != 0)
+ return 0;
+
+ return res.count_crtcs > 0 && res.count_connectors > 0 && res.count_encoders > 0;
+}
+
drm_public drmModeResPtr drmModeGetResources(int fd)
{
struct drm_mode_card_res res, counts;
@@ -683,6 +688,7 @@ drm_public void drmModeFreeProperty(drmModePropertyPtr ptr)
drmFree(ptr->values);
drmFree(ptr->enums);
+ drmFree(ptr->blob_ids);
drmFree(ptr);
}
@@ -800,21 +806,13 @@ drm_public int drmCheckModesettingSupported(const char *busid)
if (found)
return 0;
#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
- char kbusid[1024], sbusid[1024];
+ char sbusid[1024];
char oid[128];
- int domain, bus, dev, func;
int i, modesetting, ret;
size_t len;
- ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev,
- &func);
- if (ret != 4)
- return -EINVAL;
- snprintf(kbusid, sizeof(kbusid), "pci:%04x:%02x:%02x.%d", domain, bus,
- dev, func);
-
/* How many GPUs do we expect in the machine ? */
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < 10; i++) {
snprintf(oid, sizeof(oid), "hw.dri.%d.busid", i);
len = sizeof(sbusid);
ret = sysctlbyname(oid, sbusid, &len, NULL, 0);
@@ -823,7 +821,7 @@ drm_public int drmCheckModesettingSupported(const char *busid)
continue;
return -EINVAL;
}
- if (strcmp(sbusid, kbusid) != 0)
+ if (strcmp(sbusid, busid) != 0)
continue;
snprintf(oid, sizeof(oid), "hw.dri.%d.modesetting", i);
len = sizeof(modesetting);
@@ -1594,3 +1592,38 @@ drmModeRevokeLease(int fd, uint32_t lessee_id)
return 0;
return -errno;
}
+
+drm_public drmModeFB2Ptr
+drmModeGetFB2(int fd, uint32_t fb_id)
+{
+ struct drm_mode_fb_cmd2 get = {
+ .fb_id = fb_id,
+ };
+ drmModeFB2Ptr ret;
+ int err;
+
+ err = DRM_IOCTL(fd, DRM_IOCTL_MODE_GETFB2, &get);
+ if (err != 0)
+ return NULL;
+
+ ret = drmMalloc(sizeof(drmModeFB2));
+ if (!ret)
+ return NULL;
+
+ ret->fb_id = fb_id;
+ ret->width = get.width;
+ ret->height = get.height;
+ ret->pixel_format = get.pixel_format;
+ ret->flags = get.flags;
+ ret->modifier = get.modifier[0];
+ memcpy(ret->handles, get.handles, sizeof(uint32_t) * 4);
+ memcpy(ret->pitches, get.pitches, sizeof(uint32_t) * 4);
+ memcpy(ret->offsets, get.offsets, sizeof(uint32_t) * 4);
+
+ return ret;
+}
+
+drm_public void drmModeFreeFB2(drmModeFB2Ptr ptr)
+{
+ drmFree(ptr);
+}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index a32902f7..72696782 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -41,13 +41,13 @@ extern "C" {
#endif
#include <drm.h>
+#include <drm_mode.h>
+#include <stddef.h>
+#include <stdint.h>
/*
* This is the interface for modesetting for drm.
*
- * In order to use this interface you must include either <stdint.h> or another
- * header defining uint32_t, int32_t and uint16_t.
- *
* It aims to provide a randr1.2 compatible interface for modesettings in the
* kernel, the interface is also meant to be used by libraries like EGL.
*
@@ -60,120 +60,6 @@ extern "C" {
*/
/*
- * If we pickup an old version of drm.h which doesn't include drm_mode.h
- * we should redefine defines. This is so that builds doesn't breaks with
- * new libdrm on old kernels.
- */
-#ifndef _DRM_MODE_H
-
-#define DRM_DISPLAY_INFO_LEN 32
-#define DRM_CONNECTOR_NAME_LEN 32
-#define DRM_DISPLAY_MODE_LEN 32
-#define DRM_PROP_NAME_LEN 32
-
-#define DRM_MODE_TYPE_BUILTIN (1<<0)
-#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
-#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN)
-#define DRM_MODE_TYPE_PREFERRED (1<<3)
-#define DRM_MODE_TYPE_DEFAULT (1<<4)
-#define DRM_MODE_TYPE_USERDEF (1<<5)
-#define DRM_MODE_TYPE_DRIVER (1<<6)
-
-/* Video mode flags */
-/* bit compatible with the xorg definitions. */
-#define DRM_MODE_FLAG_PHSYNC (1<<0)
-#define DRM_MODE_FLAG_NHSYNC (1<<1)
-#define DRM_MODE_FLAG_PVSYNC (1<<2)
-#define DRM_MODE_FLAG_NVSYNC (1<<3)
-#define DRM_MODE_FLAG_INTERLACE (1<<4)
-#define DRM_MODE_FLAG_DBLSCAN (1<<5)
-#define DRM_MODE_FLAG_CSYNC (1<<6)
-#define DRM_MODE_FLAG_PCSYNC (1<<7)
-#define DRM_MODE_FLAG_NCSYNC (1<<8)
-#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
-#define DRM_MODE_FLAG_BCAST (1<<10)
-#define DRM_MODE_FLAG_PIXMUX (1<<11)
-#define DRM_MODE_FLAG_DBLCLK (1<<12)
-#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
-#define DRM_MODE_FLAG_3D_MASK (0x1f<<14)
-#define DRM_MODE_FLAG_3D_NONE (0<<14)
-#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14)
-#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14)
-#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14)
-#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (4<<14)
-#define DRM_MODE_FLAG_3D_L_DEPTH (5<<14)
-#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (6<<14)
-#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14)
-#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14)
-
-/* DPMS flags */
-/* bit compatible with the xorg definitions. */
-#define DRM_MODE_DPMS_ON 0
-#define DRM_MODE_DPMS_STANDBY 1
-#define DRM_MODE_DPMS_SUSPEND 2
-#define DRM_MODE_DPMS_OFF 3
-
-/* Scaling mode options */
-#define DRM_MODE_SCALE_NON_GPU 0
-#define DRM_MODE_SCALE_FULLSCREEN 1
-#define DRM_MODE_SCALE_NO_SCALE 2
-#define DRM_MODE_SCALE_ASPECT 3
-
-/* Dithering mode options */
-#define DRM_MODE_DITHERING_OFF 0
-#define DRM_MODE_DITHERING_ON 1
-
-#define DRM_MODE_ENCODER_NONE 0
-#define DRM_MODE_ENCODER_DAC 1
-#define DRM_MODE_ENCODER_TMDS 2
-#define DRM_MODE_ENCODER_LVDS 3
-#define DRM_MODE_ENCODER_TVDAC 4
-#define DRM_MODE_ENCODER_VIRTUAL 5
-#define DRM_MODE_ENCODER_DSI 6
-#define DRM_MODE_ENCODER_DPMST 7
-#define DRM_MODE_ENCODER_DPI 8
-
-#define DRM_MODE_SUBCONNECTOR_Automatic 0
-#define DRM_MODE_SUBCONNECTOR_Unknown 0
-#define DRM_MODE_SUBCONNECTOR_DVID 3
-#define DRM_MODE_SUBCONNECTOR_DVIA 4
-#define DRM_MODE_SUBCONNECTOR_Composite 5
-#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
-#define DRM_MODE_SUBCONNECTOR_Component 8
-#define DRM_MODE_SUBCONNECTOR_SCART 9
-
-#define DRM_MODE_CONNECTOR_Unknown 0
-#define DRM_MODE_CONNECTOR_VGA 1
-#define DRM_MODE_CONNECTOR_DVII 2
-#define DRM_MODE_CONNECTOR_DVID 3
-#define DRM_MODE_CONNECTOR_DVIA 4
-#define DRM_MODE_CONNECTOR_Composite 5
-#define DRM_MODE_CONNECTOR_SVIDEO 6
-#define DRM_MODE_CONNECTOR_LVDS 7
-#define DRM_MODE_CONNECTOR_Component 8
-#define DRM_MODE_CONNECTOR_9PinDIN 9
-#define DRM_MODE_CONNECTOR_DisplayPort 10
-#define DRM_MODE_CONNECTOR_HDMIA 11
-#define DRM_MODE_CONNECTOR_HDMIB 12
-#define DRM_MODE_CONNECTOR_TV 13
-#define DRM_MODE_CONNECTOR_eDP 14
-#define DRM_MODE_CONNECTOR_VIRTUAL 15
-#define DRM_MODE_CONNECTOR_DSI 16
-#define DRM_MODE_CONNECTOR_DPI 17
-
-#define DRM_MODE_PROP_PENDING (1<<0)
-#define DRM_MODE_PROP_RANGE (1<<1)
-#define DRM_MODE_PROP_IMMUTABLE (1<<2)
-#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
-#define DRM_MODE_PROP_BLOB (1<<4)
-
-#define DRM_MODE_CURSOR_BO (1<<0)
-#define DRM_MODE_CURSOR_MOVE (1<<1)
-
-#endif /* _DRM_MODE_H */
-
-
-/*
* Feature defines
*
* Just because these are defined doesn't mean that the kernel
@@ -223,6 +109,19 @@ typedef struct _drmModeFB {
uint32_t handle;
} drmModeFB, *drmModeFBPtr;
+typedef struct _drmModeFB2 {
+ uint32_t fb_id;
+ uint32_t width, height;
+ uint32_t pixel_format; /* fourcc code from drm_fourcc.h */
+ uint64_t modifier; /* applies to all buffers */
+ uint32_t flags;
+
+ /* per-plane GEM handle; may be duplicate entries for multiple planes */
+ uint32_t handles[4];
+ uint32_t pitches[4]; /* bytes */
+ uint32_t offsets[4]; /* bytes */
+} drmModeFB2, *drmModeFB2Ptr;
+
typedef struct drm_clip_rect drmModeClip, *drmModeClipPtr;
typedef struct _drmModePropertyBlob {
@@ -273,6 +172,18 @@ typedef struct _drmModeEncoder {
uint32_t possible_clones;
} drmModeEncoder, *drmModeEncoderPtr;
+/**
+ * Describes the connector status.
+ *
+ * DRM_MODE_CONNECTED means that the connector has a sink plugged in.
+ * DRM_MODE_DISCONNECTED means the contrary. DRM_MODE_UNKNOWNCONNECTION is used
+ * when it could be either.
+ *
+ * User-space should first try to enable DRM_MODE_CONNECTED connectors and
+ * ignore other connectors. If there are no DRM_MODE_CONNECTED connectors,
+ * user-space should then try to probe and enable DRM_MODE_UNKNOWNCONNECTION
+ * connectors.
+ */
typedef enum {
DRM_MODE_CONNECTED = 1,
DRM_MODE_DISCONNECTED = 2,
@@ -341,6 +252,7 @@ typedef struct _drmModePlaneRes {
extern void drmModeFreeModeInfo( drmModeModeInfoPtr ptr );
extern void drmModeFreeResources( drmModeResPtr ptr );
extern void drmModeFreeFB( drmModeFBPtr ptr );
+extern void drmModeFreeFB2( drmModeFB2Ptr ptr );
extern void drmModeFreeCrtc( drmModeCrtcPtr ptr );
extern void drmModeFreeConnector( drmModeConnectorPtr ptr );
extern void drmModeFreeEncoder( drmModeEncoderPtr ptr );
@@ -348,6 +260,13 @@ extern void drmModeFreePlane( drmModePlanePtr ptr );
extern void drmModeFreePlaneResources(drmModePlaneResPtr ptr);
/**
+ * Check whether the DRM node supports Kernel Mode-Setting.
+ *
+ * Returns 1 if suitable for KMS, 0 otherwise.
+ */
+extern int drmIsKMS(int fd);
+
+/**
* Retrieves all of the resources associated with a card.
*/
extern drmModeResPtr drmModeGetResources(int fd);
@@ -360,6 +279,7 @@ extern drmModeResPtr drmModeGetResources(int fd);
* Retrieve information about framebuffer bufferId
*/
extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId);
+extern drmModeFB2Ptr drmModeGetFB2(int fd, uint32_t bufferId);
/**
* Creates a new framebuffer with an buffer object as its scanout buffer.
@@ -530,14 +450,14 @@ extern int drmModeCreateLease(int fd, const uint32_t *objects, int num_objects,
typedef struct drmModeLesseeList {
uint32_t count;
- uint32_t lessees[0];
+ uint32_t lessees[];
} drmModeLesseeListRes, *drmModeLesseeListPtr;
extern drmModeLesseeListPtr drmModeListLessees(int fd);
typedef struct drmModeObjectList {
uint32_t count;
- uint32_t objects[0];
+ uint32_t objects[];
} drmModeObjectListRes, *drmModeObjectListPtr;
extern drmModeObjectListPtr drmModeGetLease(int fd);