diff --git a/config/graphic b/config/graphic index 2c122b4877..f80b3c7c37 100644 --- a/config/graphic +++ b/config/graphic @@ -107,7 +107,7 @@ get_graphicdrivers() { fi if listcontains "${GRAPHIC_DRIVERS}" "vc4"; then - GALLIUM_DRIVERS+=" vc4" + GALLIUM_DRIVERS+=" vc4 v3d kmsro" V4L2_SUPPORT="yes" VAAPI_SUPPORT="no" VDPAU_SUPPORT="no" diff --git a/packages/devel/libcec/package.mk b/packages/devel/libcec/package.mk index 2de020abc6..11fc693a26 100644 --- a/packages/devel/libcec/package.mk +++ b/packages/devel/libcec/package.mk @@ -19,7 +19,7 @@ PKG_CMAKE_OPTS_TARGET="-DBUILD_SHARED_LIBS=1 \ -DHAVE_AOCEC_API=0 -DHAVE_AMLOGIC_API=0 \ -DHAVE_GIT_BIN=0" -if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then +if [ "$PROJECT" = "RPi" ]; then PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET bcm2835-driver" fi @@ -34,7 +34,7 @@ if [ "$CEC_FRAMEWORK_SUPPORT" = "yes" ]; then fi pre_configure_target() { - if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then + if [ "$PROJECT" = "RPi" ]; then # detecting RPi support fails without -lvchiq_arm export LDFLAGS="$LDFLAGS -lvchiq_arm" fi diff --git a/packages/graphics/bcm2835-driver/package.mk b/packages/graphics/bcm2835-driver/package.mk index e6c387260e..e27ed5302b 100644 --- a/packages/graphics/bcm2835-driver/package.mk +++ b/packages/graphics/bcm2835-driver/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="bcm2835-driver" -PKG_VERSION="fd15e0700e45d9b7db83e30696aba299b9f2f31d" -PKG_SHA256="6324b4638b7b3f906469a1d2b94902f608436279749f167ade70e68c5c4c79a7" +PKG_VERSION="2b7c80a066c9d72dd0703f574ab2f27b3c1c3c3d" +PKG_SHA256="3cc783f4acffbcf52b8c303fbf497ed681c1c82210cdd005ccc383742fc07bbc" PKG_LICENSE="nonfree" PKG_SITE="http://www.broadcom.com" PKG_URL="${DISTRO_SRC}/${PKG_NAME}-${PKG_VERSION}.tar.xz" @@ -22,15 +22,31 @@ fi make_target() { # Install vendor header files mkdir -p ${SYSROOT_PREFIX}/usr/include - cp -PRv ${PKG_FLOAT}/opt/vc/include/* ${SYSROOT_PREFIX}/usr/include + if [ "${OPENGLES}" = "bcm2835-driver" ]; then + cp -PRv ${PKG_FLOAT}/opt/vc/include/* ${SYSROOT_PREFIX}/usr/include + else + for f in $(cd ${PKG_FLOAT}/opt/vc/include; ls | grep -v "GL"); do + cp -PRv ${PKG_FLOAT}/opt/vc/include/$f ${SYSROOT_PREFIX}/usr/include + done + fi # Install EGL, OpenGL ES, Open VG, etc. vendor libs & pkgconfigs mkdir -p ${SYSROOT_PREFIX}/usr/lib - cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.so ${SYSROOT_PREFIX}/usr/lib - ln -sf ${SYSROOT_PREFIX}/usr/lib/libbrcmEGL.so ${SYSROOT_PREFIX}/usr/lib/libEGL.so - ln -sf ${SYSROOT_PREFIX}/usr/lib/libbrcmGLESv2.so ${SYSROOT_PREFIX}/usr/lib/libGLESv2.so - cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.a ${SYSROOT_PREFIX}/usr/lib - cp -PRv ${PKG_FLOAT}/opt/vc/lib/pkgconfig ${SYSROOT_PREFIX}/usr/lib + if [ "${OPENGLES}" = "bcm2835-driver" ]; then + cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.so ${SYSROOT_PREFIX}/usr/lib + ln -sf ${SYSROOT_PREFIX}/usr/lib/libbrcmEGL.so ${SYSROOT_PREFIX}/usr/lib/libEGL.so + ln -sf ${SYSROOT_PREFIX}/usr/lib/libbrcmGLESv2.so ${SYSROOT_PREFIX}/usr/lib/libGLESv2.so + cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.a ${SYSROOT_PREFIX}/usr/lib + cp -PRv ${PKG_FLOAT}/opt/vc/lib/pkgconfig ${SYSROOT_PREFIX}/usr/lib + else + for f in $(cd ${PKG_FLOAT}/opt/vc/lib; ls *.so *.a | grep -Ev "^lib(EGL|GL)"); do + cp -PRv ${PKG_FLOAT}/opt/vc/lib/$f ${SYSROOT_PREFIX}/usr/lib + done + mkdir -p ${SYSROOT_PREFIX}/usr/lib/pkgconfig + for f in $(cd ${PKG_FLOAT}/opt/vc/lib/pkgconfig; ls | grep -v "gl"); do + cp -PRv ${PKG_FLOAT}/opt/vc/lib/pkgconfig/$f ${SYSROOT_PREFIX}/usr/lib/pkgconfig + done + fi # Update prefix in vendor pkgconfig files for PKG_CONFIGS in $(find "${SYSROOT_PREFIX}/usr/lib" -type f -name "*.pc" 2>/dev/null); do @@ -46,11 +62,17 @@ make_target() { makeinstall_target() { # Install EGL, OpenGL ES and other vendor libs mkdir -p ${INSTALL}/usr/lib - cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.so ${INSTALL}/usr/lib - ln -sf /usr/lib/libbrcmEGL.so ${INSTALL}/usr/lib/libEGL.so - ln -sf /usr/lib/libbrcmEGL.so ${INSTALL}/usr/lib/libEGL.so.1 - ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so - ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so.2 + if [ "${OPENGLES}" = "bcm2835-driver" ]; then + cp -PRv ${PKG_FLOAT}/opt/vc/lib/*.so ${INSTALL}/usr/lib + ln -sf /usr/lib/libbrcmEGL.so ${INSTALL}/usr/lib/libEGL.so + ln -sf /usr/lib/libbrcmEGL.so ${INSTALL}/usr/lib/libEGL.so.1 + ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so + ln -sf /usr/lib/libbrcmGLESv2.so ${INSTALL}/usr/lib/libGLESv2.so.2 + else + for f in $(cd ${PKG_FLOAT}/opt/vc/lib; ls *.so | grep -Ev "^lib(EGL|GL)"); do + cp -PRv ${PKG_FLOAT}/opt/vc/lib/$f ${INSTALL}/usr/lib + done + fi # Install useful tools mkdir -p ${INSTALL}/usr/bin @@ -68,5 +90,7 @@ makeinstall_target() { post_install() { # unbind Framebuffer console - enable_service unbind-console.service + if [ "${OPENGLES}" = "bcm2835-driver" ]; then + enable_service unbind-console.service + fi } diff --git a/packages/linux-firmware/brcmfmac_sdio-firmware-rpi/patches/brcmfmac_sdio-firmware-rpi-001-sync-with-raspbian-buster.patch b/packages/linux-firmware/brcmfmac_sdio-firmware-rpi/patches/brcmfmac_sdio-firmware-rpi-001-sync-with-raspbian-buster.patch new file mode 100644 index 0000000000..a3201b9d00 --- /dev/null +++ b/packages/linux-firmware/brcmfmac_sdio-firmware-rpi/patches/brcmfmac_sdio-firmware-rpi-001-sync-with-raspbian-buster.patch @@ -0,0 +1,21 @@ +diff -ru brcmfmac_sdio-firmware-rpi.orig/firmware/brcm/brcmfmac43455-sdio.txt brcmfmac_sdio-firmware-rpi/firmware/brcm/brcmfmac43455-sdio.txt +--- brcmfmac_sdio-firmware-rpi.orig/firmware/brcm/brcmfmac43455-sdio.txt 2019-01-28 20:44:58.000000000 +0100 ++++ brcmfmac_sdio-firmware-rpi/firmware/brcm/brcmfmac43455-sdio.txt 2019-06-11 13:09:30.388579306 +0200 +@@ -21,7 +21,7 @@ + # bit1 for btcoex + boardflags=0x00480201 + boardflags2=0x40800000 +-boardflags3=0x48200100 ++boardflags3=0x44200100 + phycal_tempdelta=15 + rxchain=1 + txchain=1 +@@ -91,7 +91,7 @@ + cbfilttype=1 + fdsslevel_ch11=6 + +-# Experimental Bluetooth coexistence parameters from Cypress ++# Improved Bluetooth coexistence parameters from Cypress + btc_mode=1 + btc_params8=0x4e20 + btc_params1=0x7530 diff --git a/packages/linux/package.mk b/packages/linux/package.mk index 23b4209360..4a6ea8d6ef 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -23,8 +23,8 @@ case "$LINUX" in PKG_SOURCE_NAME="linux-$LINUX-$PKG_VERSION.tar.gz" ;; raspberrypi) - PKG_VERSION="5040b4b78e4cb74a6364d9a7c6cca0385e2dffd8" # 4.19.50 - PKG_SHA256="134a9821db00c3c826dfeb86be9439a4d0c5b10796f7173a2e5d5728ef2fc979" + PKG_VERSION="71d47f4c4bd7fd395b87c474498187b2f9be8751" + PKG_SHA256="d1ef4b20f0e0435ed1792eccee99d430b06404ba114dbe3f17e0af616a9b748d" PKG_URL="https://github.com/raspberrypi/linux/archive/$PKG_VERSION.tar.gz" PKG_SOURCE_NAME="linux-$LINUX-$PKG_VERSION.tar.gz" ;; diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index 60e6686f10..443565d2f7 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -31,6 +31,10 @@ case $KODI_VENDOR in ;; esac +if [ "$PROJECT" = "RPi" ]; then + PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET bcm2835-driver" +fi + configure_package() { # Single threaded LTO is very slow so rely on Kodi for parallel LTO support if [ "$LTO_SUPPORT" = "yes" ] && ! build_with_debug; then diff --git a/packages/multimedia/ffmpeg/package.mk b/packages/multimedia/ffmpeg/package.mk index 1ca7bc3148..0ea4308563 100644 --- a/packages/multimedia/ffmpeg/package.mk +++ b/packages/multimedia/ffmpeg/package.mk @@ -57,7 +57,7 @@ else PKG_FFMPEG_DEBUG="--disable-debug --enable-stripping" fi -if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then +if [ "$PROJECT" = "RPi" ]; then PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET bcm2835-driver" fi @@ -80,7 +80,7 @@ pre_configure_target() { cd $PKG_BUILD rm -rf .$TARGET_NAME - if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then + if [ "$PROJECT" = "RPi" ]; then PKG_FFMPEG_LIBS="-lbcm_host -lvcos -lvchiq_arm -lmmal -lmmal_core -lmmal_util -lvcsm" PKG_FFMPEG_RPI="--enable-rpi" else diff --git a/packages/tools/bcm2835-bootloader/package.mk b/packages/tools/bcm2835-bootloader/package.mk index dd28f623a9..4c2e0cbef4 100644 --- a/packages/tools/bcm2835-bootloader/package.mk +++ b/packages/tools/bcm2835-bootloader/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="bcm2835-bootloader" -PKG_VERSION="fd15e0700e45d9b7db83e30696aba299b9f2f31d" -PKG_SHA256="c9d32c2355ce4116206b3deae3e340545f345441c0c93ba2347971784fd327ff" +PKG_VERSION="2b7c80a066c9d72dd0703f574ab2f27b3c1c3c3d" +PKG_SHA256="76acf720350bac0458689f563947a51988617f4eb2e83334f5ef1565faa4e350" PKG_ARCH="arm" PKG_LICENSE="nonfree" PKG_SITE="http://www.broadcom.com" @@ -17,8 +17,13 @@ makeinstall_target() { mkdir -p $INSTALL/usr/share/bootloader cp -PRv LICENCE* $INSTALL/usr/share/bootloader cp -PRv bootcode.bin $INSTALL/usr/share/bootloader - cp -PRv fixup_x.dat $INSTALL/usr/share/bootloader/fixup.dat - cp -PRv start_x.elf $INSTALL/usr/share/bootloader/start.elf + if [ "$DEVICE" = "RPi4" ]; then + cp -PRv fixup4x.dat $INSTALL/usr/share/bootloader/fixup.dat + cp -PRv start4x.elf $INSTALL/usr/share/bootloader/start.elf + else + cp -PRv fixup_x.dat $INSTALL/usr/share/bootloader/fixup.dat + cp -PRv start_x.elf $INSTALL/usr/share/bootloader/start.elf + fi find_file_path config/dt-blob.bin && cp -PRv $FOUND_PATH $INSTALL/usr/share/bootloader diff --git a/packages/tools/bcm2835-bootloader/release b/packages/tools/bcm2835-bootloader/release index fbf9e5c545..a2e1ce9aa9 100755 --- a/packages/tools/bcm2835-bootloader/release +++ b/packages/tools/bcm2835-bootloader/release @@ -5,10 +5,10 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) mkdir -p $RELEASE_DIR/3rdparty/bootloader - cp -PR $BUILD/bcm2835-bootloader-*/LICENCE* $RELEASE_DIR/3rdparty/bootloader/ - cp -PR $BUILD/bcm2835-bootloader-*/bootcode.bin $RELEASE_DIR/3rdparty/bootloader/ - cp -PR $BUILD/bcm2835-bootloader-*/fixup_x.dat $RELEASE_DIR/3rdparty/bootloader/fixup.dat - cp -PR $BUILD/bcm2835-bootloader-*/start_x.elf $RELEASE_DIR/3rdparty/bootloader/start.elf + cp -PR $INSTALL/usr/share/bootloader/LICENCE* $RELEASE_DIR/3rdparty/bootloader/ + cp -PR $INSTALL/usr/share/bootloader/bootcode.bin $RELEASE_DIR/3rdparty/bootloader/ + cp -PR $INSTALL/usr/share/bootloader/fixup.dat $RELEASE_DIR/3rdparty/bootloader/ + cp -PR $INSTALL/usr/share/bootloader/start.elf $RELEASE_DIR/3rdparty/bootloader/ if [ -f $(get_build_dir slice-firmware)/dt-blob.bin ]; then cp -PR $(get_build_dir slice-firmware)/dt-blob.bin $RELEASE_DIR/3rdparty/bootloader/ fi diff --git a/packages/tools/bcmstat/patches/bcmstat-001-add-patch-from-milhouse.patch b/packages/tools/bcmstat/patches/bcmstat-001-add-patch-from-milhouse.patch new file mode 100644 index 0000000000..4ab97f6720 --- /dev/null +++ b/packages/tools/bcmstat/patches/bcmstat-001-add-patch-from-milhouse.patch @@ -0,0 +1,400 @@ +From c13ba8541ba6701dc4a851ea0940884e2e6020f2 Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Fri, 1 Mar 2019 15:58:44 +0000 +Subject: [PATCH 1/5] add rpi4 + +--- + bcmstat.sh | 32 ++++++++++++++++++-------------- + 1 file changed, 18 insertions(+), 14 deletions(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index fa8ee7e..b90392e 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -44,7 +44,7 @@ else: + + GITHUB = "https://raw.github.com/MilhouseVH/bcmstat/master" + ANALYTICS = "http://goo.gl/edu1jG" +-VERSION = "0.5.1" ++VERSION = "0.5.2" + + VCGENCMD = None + VCDBGCMD = None +@@ -60,7 +60,7 @@ SYSINFO = {} + # NEW 23: will be 1 for the new scheme, 0 for the old scheme + # MEMSIZE 20: 0=256M 1=512M 2=1G + # MANUFACTURER 16: 0=SONY 1=EGOMAN 2=EMBEST 3=SONY JAPAN 4=EMBEST +-# PROCESSOR 12: 0=2835 1=2836 2=2837 ++# PROCESSOR 12: 0=2835 1=2836 2=2837, 3=2838 + # TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODELB 5=ALPHA 6=CM 8=Pi3 9=Pi0 10=CM3 12=Pi0W + # REV 00: 0=REV0 1=REV1 2=REV2 3=REV3 + +@@ -84,10 +84,10 @@ class RPIHardware(): + + # Note: Some of these memory sizes and processors are fictional and relate to unannounced products - logic would + # dictate such products may exist at some point in the future, but it's only guesswork. +- self.memsizes = ["256MB", "512MB", "1GB", "2GB", "4GB"] ++ self.memsizes = ["256MB", "512MB", "1GB", "2GB", "4GB", "8GB"] + self.manufacturers = ["Sony UK", "Egoman", "Embest", "Sony Japan", "Embest", "Stadium"] + self.processors = ["2835", "2836", "2837", "2838", "2839", "2840"] +- self.models = ["Model A", "Model B", "Model A+", "Model B+", "Pi2 Model B", "Alpha", "CM1", "Unknown", "Pi3", "Pi0", "CM3", "Unknown", "Pi0 W", "Pi3 Model B+"] ++ self.models = ["Model A", "Model B", "Model A+", "Model B+", "Pi2 Model B", "Alpha", "CM1", "Unknown", "Pi3", "Pi0", "CM3", "Unknown", "Pi0 W", "Pi3 Model B+", "Pi3 Model A+", "Unknown", "CM3+", "Pi4 Model B"] + self.pcbs = ["Unknown", "Pi3 Rev1.0", "Pi3 Rev1.2", "Pi2 2837 Rev1.1", "Pi2 2836", "Pi1 B+ Rev 1.1", "Pi0", "Pi1 B Rev2.0", "Pi2 (2837) Rev1.0", "Pi0 W", "Pi2 (2837) Rev1.2", "Pi3 B+"] + + self.set_rev_code(rev_code) +@@ -909,8 +909,8 @@ def ShowHeadings(display_flags, sysinfo): + HDR1 = "%s RX kB/s TX kB/s" % HDR1 + HDR2 = "%s ======= =======" % HDR2 + else: +- HDR1 = "%s RX B/s TX B/s" % HDR1 +- HDR2 = "%s ========== ==========" % HDR2 ++ HDR1 = "%s RX B/s TX B/s" % HDR1 ++ HDR2 = "%s =========== ===========" % HDR2 + + if display_flags["utilisation"]: + HDR1 = "%s %%user %%nice %%sys %%idle %%iowt %%irq %%s/irq %%total" % HDR1 +@@ -937,8 +937,12 @@ def ShowHeadings(display_flags, sysinfo): + HDR2 = "%s ===========" % HDR2 + + if display_flags["cpu_mem"]: +- HDR1 = "%s Mem Free / %%used" % HDR1 +- HDR2 = "%s ================" % HDR2 ++ if display_flags["human_readable"]: ++ HDR1 = "%s MemFreeMB / %%used" % HDR1 ++ HDR2 = "%s =================" % HDR2 ++ else: ++ HDR1 = "%s MemFreeKB / %%used" % HDR1 ++ HDR2 = "%s =================" % HDR2 + if display_flags["swap"]: + HDR1 = "%s(SwUse)" % HDR1 + HDR2 = "%s=======" % HDR2 +@@ -1025,8 +1029,8 @@ def ShowStats(display_flags, sysinfo, threshold, bcm2385, irq, network, cpuload, + else: + LINE = "%s %s %s" % \ + (LINE, +- colourise(network[0], "%10s", 0.5e6, 2.5e6, 5.0e6, True), +- colourise(network[1], "%10s", 0.5e6, 2.5e6, 5.0e6, True)) ++ colourise(network[0], "%11s", 0.5e6, 2.5e6, 5.0e6, True), ++ colourise(network[1], "%11s", 0.5e6, 2.5e6, 5.0e6, True)) + + if display_flags["utilisation"]: + LINE = "%s %s %s %s %s %s %s %s %s" % \ +@@ -1071,12 +1075,12 @@ def ShowStats(display_flags, sysinfo, threshold, bcm2385, irq, network, cpuload, + if display_flags["human_readable"]: + LINE = "%s %s / %s" % \ + (LINE, +- colourise(memory[1]/1024, "%5s MB", 60, 75, 85, True, compare=memory[2]), +- colourise(memory[2], "%4.1f%%", 60, 75, 85, False, compare=memory[2])) ++ colourise(memory[1]/1024, "%9s", 60, 75, 85, True, compare=memory[2]), ++ colourise(memory[2], "%4.1f%%", 60, 75, 85, False, compare=memory[2])) + else : +- LINE = "%s %s/%s" % \ ++ LINE = "%s %s / %s" % \ + (LINE, +- colourise(memory[1], "%7s kB", 60, 75, 85, True, compare=memory[2]), ++ colourise(memory[1], "%9s", 60, 75, 85, True, compare=memory[2]), + colourise(memory[2], "%4.1f%%", 60, 75, 85, False, compare=memory[2])) + + # Swap memory +-- +2.14.1 + + +From 390cc573319fd918dc23ee78e4ab914b30965304 Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Wed, 6 Mar 2019 11:44:40 +0000 +Subject: [PATCH 2/5] irqs: don't fail if missing + +--- + bcmstat.sh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index b90392e..3e13c97 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -452,7 +452,8 @@ def getIRQ(storage): + + irq = 0 + for i in grep("dwc", readfile("/proc/interrupts"), 1).split("\n"): +- irq += int(i) ++ if i: ++ irq += int(i) + + storage[1] = (time.time(), irq) + +-- +2.14.1 + + +From 28ffb2a403af013ad2408dd6cfad485f01a9240b Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Wed, 6 Mar 2019 12:29:29 +0000 +Subject: [PATCH 3/5] irqs: accumulate all of them + +--- + bcmstat.sh | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index 3e13c97..1db3df4 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -447,13 +447,19 @@ def colourise(display, nformat, green, yellow, red, withcomma, compare=None, add + + return nformat % cnum + +-def getIRQ(storage): ++def getIRQ(storage, sysinfo): + storage[2] = storage[1] + ++ nproc = sysinfo["nproc"] + irq = 0 +- for i in grep("dwc", readfile("/proc/interrupts"), 1).split("\n"): +- if i: +- irq += int(i) ++ for line in grep(":", readfile("/proc/interrupts")).split("\n"): ++ fields = line.split(" ") ++ if fields[0] == "FIQ:": ++ continue ++ if fields[0] == "Err:": ++ break ++ for n in range(1, nproc + 1): ++ irq += int(fields[n]) + + storage[1] = (time.time(), irq) + +@@ -1600,7 +1606,7 @@ def main(args): + HARDWARE.GetThresholdValues(UFT, STATS_THRESHOLD_CLEAR) + + getBCM283X(BCM, STATS_WITH_VOLTS) +- getIRQ(IRQ) ++ getIRQ(IRQ, sysinfo) + getNetwork(NET, INTERFACE) + + STATS_NETWORK = (NET[1][1] != "") +@@ -1655,7 +1661,7 @@ def main(args): + HARDWARE.GetThresholdValues(UFT, STATS_THRESHOLD_CLEAR) + + getBCM283X(BCM, STATS_WITH_VOLTS) +- getIRQ(IRQ) ++ getIRQ(IRQ, sysinfo) + + if STATS_NETWORK: + getNetwork(NET, INTERFACE) +-- +2.14.1 + + +From 19097fd9d91dd69ce05fe10957dfb72a2c470fcb Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Fri, 26 Apr 2019 18:30:49 +0100 +Subject: [PATCH 4/5] pmic: measure temp with option t + +--- + bcmstat.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 58 insertions(+), 16 deletions(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index 1db3df4..50fa11c 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -51,7 +51,8 @@ VCDBGCMD = None + GPU_ALLOCATED_R = None + GPU_ALLOCATED_M = None + SUDO = "" +-TMAX = 0.0 ++TCMAX = 0.0 ++TPMAX = 0.0 + LIMIT_TEMP = True + COLOUR = False + SYSINFO = {} +@@ -570,15 +571,27 @@ def getNetwork(storage, interface): + dTX = cTX - pTX + storage[0] = (dTime, [int(dRX/dTime), int(dTX/dTime), dRX, dTX]) + +-def getBCM283X(storage, STATS_WITH_VOLTS): +- global TMAX, LIMIT_TEMP ++def getBCM283X(storage, STATS_WITH_VOLTS, STATS_WITH_PMIC_TEMP): ++ global TCMAX, LIMIT_TEMP, TPMAX + #Grab temp - ignore temps of 85C as this seems to be an occasional aberration in the reading + tCore = float(readfile("/sys/class/thermal/thermal_zone0/temp")) + tCore = 0 if tCore < 0 else tCore + if LIMIT_TEMP: +- TMAX = tCore if (tCore > TMAX and tCore < 85000) else TMAX ++ TCMAX = tCore if (tCore > TCMAX and tCore < 85000) else TCMAX + else: +- TMAX = tCore if tCore > TMAX else TMAX ++ TCMAX = tCore if tCore > TCMAX else TCMAX ++ ++ if STATS_WITH_PMIC_TEMP: ++ tPMIC = vcgencmd("measure_temp pmic", split=False) ++ if tPMIC.find("error") != -1: ++ tPMIC = None ++ tPMIC_MAX = None ++ else: ++ tPMIC = float(tPMIC.split("=")[1].replace("'C","")) ++ TPMAX = tPMIC if tPMIC > TPMAX else TPMAX ++ else: ++ tPMIC = None ++ tPMIC_MAX = None + + if STATS_WITH_VOLTS: + volts = vcgencmd("measure_volts core") +@@ -594,8 +607,8 @@ def getBCM283X(storage, STATS_WITH_VOLTS): + [int(vcgencmd("measure_clock arm")) + 500000, + int(vcgencmd("measure_clock core")) + 500000, + int(vcgencmd("measure_clock h264")) + 500000, +- tCore, +- TMAX, ++ tCore, TCMAX, ++ tPMIC, TPMAX, + volts]) + + if storage[2][0] != 0: +@@ -908,8 +921,15 @@ def ShowHeadings(display_flags, sysinfo): + HDR1 = "%s Vcore " % HDR1 + HDR2 = "%s ======" % HDR2 + +- HDR1 = "%s ARM Core H264 Core Temp (Max) IRQ/s" % HDR1 +- HDR2 = "%s ======= ======= ======= =============== ======" % HDR2 ++ HDR1 = "%s ARM Core H264 Core Temp (Max)" % HDR1 ++ HDR2 = "%s ======= ======= ======= ===============" % HDR2 ++ ++ if display_flags["temp_pmic"]: ++ HDR1 = "%s PMIC Temp (Max)" % HDR1 ++ HDR2 = "%s ===============" % HDR2 ++ ++ HDR1 = "%s IRQ/s" % HDR1 ++ HDR2 = "%s ======" % HDR2 + + if display_flags["network"]: + if display_flags["human_readable"]: +@@ -1016,15 +1036,26 @@ def ShowStats(display_flags, sysinfo, threshold, bcm2385, irq, network, cpuload, + fTM = "%5.2fC" if bcm2385[4] < 100000 else "%5.1fC" + + if display_flags["core_volts"]: +- LINE = "%s %s" % (LINE, bcm2385[5]) ++ LINE = "%s %s" % (LINE, bcm2385[7]) + +- LINE = "%s %s %s %s %s (%s) %s" % \ ++ LINE = "%s %s %s %s %s (%s)" % \ + (LINE, + colourise(bcm2385[0]/1000000, "%4dMhz", arm_min, None, arm_max, False), + colourise(bcm2385[1]/1000000, "%4dMhz",core_min, None, core_max, False), + colourise(bcm2385[2]/1000000, "%4dMhz", 0, h264_min, h264_max, False), + colourise(bcm2385[3]/1000, fTC, 50.0, 70.0, 80.0, False), +- colourise(bcm2385[4]/1000, fTM, 50.0, 70.0, 80.0, False), ++ colourise(bcm2385[4]/1000, fTM, 50.0, 70.0, 80.0, False)) ++ ++ if display_flags["temp_pmic"]: ++ fTC = "%5.2fC" if bcm2385[5] < 100000 else "%5.1fC" ++ fTM = "%5.2fC" if bcm2385[6] < 100000 else "%5.1fC" ++ LINE = "%s %s (%s)" % \ ++ (LINE, ++ colourise(bcm2385[5], fTC, 50.0, 70.0, 80.0, False), ++ colourise(bcm2385[6], fTM, 50.0, 70.0, 80.0, False)) ++ ++ LINE = "%s %s" % \ ++ (LINE, + colourise(irq[0], "%6s", 500, 2500, 5000, True)) + + if display_flags["network"]: +@@ -1145,7 +1176,7 @@ def ShowStats(display_flags, sysinfo, threshold, bcm2385, irq, network, cpuload, + printn("\n%s" % LINE) + + def ShowHelp(): +- print("Usage: %s [c|m] [d#] [H#] [i ] [k] [L|N|M] [y|Y] [x|X|r|R] [p|P] [T] [g|G] [f|F] [D][A] [s|S] [q|Q] [V|U|W|C] [Z] [h]" % os.path.basename(__file__)) ++ print("Usage: %s [c|m] [d#] [H#] [i ] [k] [L|N|M] [y|Y] [x|X|r|R] [p|P] [T] [t] [g|G] [f|F] [D][A] [s|S] [q|Q] [V|U|W|C] [Z] [h]" % os.path.basename(__file__)) + print() + print("c Colourise output (white: minimal load or usage, then ascending through green, amber and red).") + print("m Monochrome output (no colourise)") +@@ -1168,6 +1199,7 @@ def ShowHelp(): + print("D Show delta memory - negative: memory allocated, positive: memory freed") + print("A Show accumulated delta memory - negative: memory allocated, positive: memory freed") + print("T Maximum temperature is normally capped at 85C - use this option to disable temperature cap") ++ print("t Show PMIC temperature (if available, ignore if not)") + print() + print("V Check version") + print("U Update to latest version if an update is available") +@@ -1365,6 +1397,7 @@ def main(args): + STATS_THRESHOLD = False + STATS_THRESHOLD_CLEAR = False + STATS_WITH_VOLTS = False ++ STATS_WITH_PMIC_TEMP = False + STATS_CPU_MEM = False + STATS_UTILISATION = False + SIMPLE_UTILISATION = False +@@ -1495,6 +1528,9 @@ def main(args): + elif a1 == "T": + LIMIT_TEMP = False + ++ elif a1 == "t": ++ STATS_WITH_PMIC_TEMP = True ++ + elif a1 == "D": + STATS_DELTAS = True + +@@ -1605,8 +1641,12 @@ def main(args): + if STATS_THRESHOLD: + HARDWARE.GetThresholdValues(UFT, STATS_THRESHOLD_CLEAR) + +- getBCM283X(BCM, STATS_WITH_VOLTS) ++ getBCM283X(BCM, STATS_WITH_VOLTS, STATS_WITH_PMIC_TEMP) ++ if BCM[1][1][5] == None: ++ STATS_WITH_PMIC_TEMP = False ++ + getIRQ(IRQ, sysinfo) ++ + getNetwork(NET, INTERFACE) + + STATS_NETWORK = (NET[1][1] != "") +@@ -1642,7 +1682,8 @@ def main(args): + "gpu_malloc": STATS_GPU_M, + "swap": (SWAP_ENABLED and INCLUDE_SWAP), + "deltas": STATS_DELTAS, +- "accumulated": STATS_ACCUMULATED} ++ "accumulated": STATS_ACCUMULATED, ++ "temp_pmic": STATS_WITH_PMIC_TEMP} + + #Store peak values + PEAKVALUES = {"01#IRQ":0, "02#RX":0, "03#TX":0} +@@ -1660,7 +1701,8 @@ def main(args): + if STATS_THRESHOLD: + HARDWARE.GetThresholdValues(UFT, STATS_THRESHOLD_CLEAR) + +- getBCM283X(BCM, STATS_WITH_VOLTS) ++ getBCM283X(BCM, STATS_WITH_VOLTS, STATS_WITH_PMIC_TEMP) ++ + getIRQ(IRQ, sysinfo) + + if STATS_NETWORK: +-- +2.14.1 + + +From 987ad9c3dd102df5c7f027f8fb0cbc6d7e989d79 Mon Sep 17 00:00:00 2001 +From: MilhouseVH +Date: Tue, 11 Jun 2019 02:31:07 +0100 +Subject: [PATCH 5/5] memory: treat SReclaimable as free mem + +--- + bcmstat.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/bcmstat.sh b/bcmstat.sh +index 50fa11c..6a2a549 100755 +--- a/bcmstat.sh ++++ b/bcmstat.sh +@@ -629,7 +629,7 @@ def getMemory(storage, include_swap): + + for line in readfile("/proc/meminfo").split("\n"): + field_groups = re.search("^(.*):[ ]*([0-9]*) .*$", line) +- if field_groups.group(1) in ["MemFree", "Buffers", "Cached"]: ++ if field_groups.group(1) in ["MemFree", "Buffers", "Cached", "SReclaimable"]: + MEMFREE += int(field_groups.group(2)) + elif field_groups.group(1) == "MemTotal": + MEMTOTAL = int(field_groups.group(2)) +-- +2.14.1 + diff --git a/projects/RPi/devices/RPi/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch b/projects/RPi/devices/RPi/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch new file mode 120000 index 0000000000..f1fa7c5050 --- /dev/null +++ b/projects/RPi/devices/RPi/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch @@ -0,0 +1 @@ +../../../RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch \ No newline at end of file diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch b/projects/RPi/devices/RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-99.1003-pfcd_hevc_optimisations.patch rename to projects/RPi/devices/RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch diff --git a/projects/RPi/devices/RPi4/config/config.txt b/projects/RPi/devices/RPi4/config/config.txt new file mode 100644 index 0000000000..9e2b74b9ad --- /dev/null +++ b/projects/RPi/devices/RPi4/config/config.txt @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) +################################################################################ +# Bootloader configuration - config.txt +################################################################################ + +################################################################################ +# Memory (System/GPU configuration ) +################################################################################ + +# Default GPU memory split - at least 288M is needed for some 4k HEVC files +gpu_mem=320 + +################################################################################ +# For overclocking and various other settings, see: +# https://www.raspberrypi.org/documentation/configuration/config-txt.md +################################################################################ +# Set 'force_turbo=1' to disable dynamic overclocking and enable overclocking always. +force_turbo=0 + +# Force HDMI even if unplugged or powered off +# hdmi_force_hotplug=1 + +# Doesn't sent initial active source message. +# Avoids bringing CEC (enabled TV) out of standby and channel switch when +# rebooting. +hdmi_ignore_cec_init=1 + +################################################################################ +# End of default configuration +################################################################################ + +################################################################################ +# Include distribution specific config file if it exists. +################################################################################ +[all] +include distroconfig.txt diff --git a/projects/RPi/devices/RPi4/config/distroconfig.txt b/projects/RPi/devices/RPi4/config/distroconfig.txt new file mode 100644 index 0000000000..a5670d0691 --- /dev/null +++ b/projects/RPi/devices/RPi4/config/distroconfig.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +# WARNING: DO NOT EDIT THIS FILE - IT WILL BE OVERWRITTEN WHEN UPGRADING! +dtoverlay=vc4-fkms-v3d +disable_overscan=1 diff --git a/projects/RPi/devices/RPi4/kodi/appliance.xml b/projects/RPi/devices/RPi4/kodi/appliance.xml new file mode 100644 index 0000000000..472aaf7971 --- /dev/null +++ b/projects/RPi/devices/RPi4/kodi/appliance.xml @@ -0,0 +1,14 @@ + + +
+ + + + true + 3 + + + +
+
+ diff --git a/projects/RPi/devices/RPi4/linux/linux.arm.conf b/projects/RPi/devices/RPi4/linux/linux.arm.conf new file mode 100644 index 0000000000..eb91978071 --- /dev/null +++ b/projects/RPi/devices/RPi4/linux/linux.arm.conf @@ -0,0 +1,5422 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 4.19.46 Kernel Configuration +# + +# +# Compiler: gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0 +# +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=70200 +CONFIG_CLANG_VERSION=0 +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_HOSTNAME="@DISTRONAME@" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_USELIB is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +CONFIG_CPU_ISOLATION=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +CONFIG_TREE_SRCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_CGROUPS=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +# CONFIG_MEMCG_SWAP is not set +CONFIG_MEMCG_KMEM=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_CGROUP_WRITEBACK=y +CONFIG_CGROUP_SCHED=y +# CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +# CONFIG_CGROUP_PIDS is not set +# CONFIG_CGROUP_RDMA is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +# CONFIG_USER_NS is not set +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_INITRAMFS_FORCE is not set +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_INITRAMFS_COMPRESSION=".gz" +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_BPF=y +CONFIG_EXPERT=y +# CONFIG_UID16 is not set +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +# CONFIG_SYSFS_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y +CONFIG_FHANDLE=y +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_PRINTK_NMI=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +CONFIG_MEMBARRIER=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_BASE_RELATIVE=y +CONFIG_BPF_SYSCALL=y +# CONFIG_USERFAULTFD is not set +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_RSEQ=y +# CONFIG_DEBUG_RSEQ is not set +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_MEMCG_SYSFS_ON is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set +CONFIG_SLUB_CPU_PARTIAL=y +CONFIG_SYSTEM_DATA_VERIFICATION=y +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_FIQ=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=3 + +# +# System Type +# +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_BITS_MAX=16 +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP1 is not set + +# +# Multiple platform selection +# + +# +# CPU Core family selection +# +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_MULTI_V6_V7=y +# CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_ARTPEC is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_AXXIA is not set +CONFIG_ARCH_BCM=y + +# +# IPROC architected SoCs +# +# CONFIG_ARCH_BCM_CYGNUS is not set +# CONFIG_ARCH_BCM_HR2 is not set +# CONFIG_ARCH_BCM_NSP is not set +# CONFIG_ARCH_BCM_5301X is not set + +# +# KONA architected SoCs +# +# CONFIG_ARCH_BCM_281XX is not set +# CONFIG_ARCH_BCM_21664 is not set +# CONFIG_ARCH_BCM_23550 is not set + +# +# Other Architectures +# +CONFIG_ARCH_BCM2835=y +# CONFIG_ARCH_BCM_53573 is not set +# CONFIG_ARCH_BCM_63XX is not set +# CONFIG_ARCH_BRCMSTB is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_DIGICOLOR is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_NPCM is not set + +# +# TI OMAP/AM/DM/DRA Family +# +# CONFIG_ARCH_OMAP3 is not set +# CONFIG_ARCH_OMAP4 is not set +# CONFIG_SOC_OMAP5 is not set +# CONFIG_SOC_AM33XX is not set +# CONFIG_SOC_AM43XX is not set +# CONFIG_SOC_DRA7XX is not set +# CONFIG_ARCH_SIRF is not set +# CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_STM32 is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_TANGO is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_WM8850 is not set +# CONFIG_ARCH_ZX is not set +# CONFIG_ARCH_ZYNQ is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_LPAE=y +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_ARM_VIRT_EXT=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_SPECTRE=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_KUSER_HELPERS=y +CONFIG_VDSO=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_DEBUG_ALIGN_RODATA=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_643719 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +# CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_773022 is not set +# CONFIG_ARM_ERRATA_818325_852422 is not set +# CONFIG_ARM_ERRATA_821420 is not set +# CONFIG_ARM_ERRATA_825619 is not set +# CONFIG_ARM_ERRATA_852421 is not set +# CONFIG_ARM_ERRATA_852423 is not set + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCI_PRI is not set +# CONFIG_PCI_PASID is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# PCI controller drivers +# + +# +# Cadence PCIe controllers support +# +# CONFIG_PCIE_CADENCE_HOST is not set +# CONFIG_PCI_FTPCI100 is not set +# CONFIG_PCI_HOST_GENERIC is not set +# CONFIG_PCIE_XILINX is not set +# CONFIG_PCI_V3_SEMI is not set +# CONFIG_PCIE_ALTERA is not set +CONFIG_PCIE_BRCMSTB=y + +# +# DesignWare PCI Core Support +# +# CONFIG_PCIE_DW_PLAT_HOST is not set +# CONFIG_PCI_LAYERSCAPE is not set + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_HAVE_ARM_ARCH_TIMER=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_ARM_PSCI is not set +CONFIG_ARCH_NR_GPIO=0 +CONFIG_HZ_FIXED=0 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_200 is not set +# CONFIG_HZ_250 is not set +CONFIG_HZ_300=y +# CONFIG_HZ_500 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=300 +CONFIG_SCHED_HRTICK=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_ARM_PATCH_IDIV=y +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_GENERIC_GUP=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +CONFIG_UACCESS_WITH_MEMCPY=y +# CONFIG_SECCOMP is not set +# CONFIG_PARAVIRT is not set +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +# CONFIG_XEN is not set + +# +# Boot options +# +CONFIG_USE_OF=y +CONFIG_ATAGS=y +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="root=/dev/ram0 rdinit=/init usbcore.autosuspend=-1" +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_CMDLINE_EXTEND=y +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_AUTO_ZRELADDR=y +# CONFIG_EFI is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set + +# +# CPU frequency scaling drivers +# +# CONFIG_CPUFREQ_DT is not set +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set +CONFIG_ARM_BCM2835_CPUFREQ=y +# CONFIG_QORIQ_CPUFREQ is not set + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# ARM CPU Idle Drivers +# +# CONFIG_ARM_CPUIDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y + +# +# Power management options +# +# CONFIG_SUSPEND is not set +# CONFIG_HIBERNATION is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_APM_EMULATION is not set +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_CPU_PM=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y + +# +# Firmware Drivers +# +# CONFIG_ARM_SCMI_PROTOCOL is not set +# CONFIG_ARM_SCPI_PROTOCOL is not set +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_RASPBERRYPI_FIRMWARE=y +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_HAVE_ARM_SMCCC=y +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# Tegra firmware driver +# +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM=y +CONFIG_CRYPTO_SHA1_ARM_NEON=y +# CONFIG_CRYPTO_SHA1_ARM_CE is not set +# CONFIG_CRYPTO_SHA2_ARM_CE is not set +CONFIG_CRYPTO_SHA256_ARM=m +# CONFIG_CRYPTO_SHA512_ARM is not set +CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m +# CONFIG_CRYPTO_AES_ARM_CE is not set +# CONFIG_CRYPTO_GHASH_ARM_CE is not set +CONFIG_CRYPTO_CRC32_ARM_CE=y +# CONFIG_CRYPTO_CHACHA20_NEON is not set +# CONFIG_VIRTUALIZATION is not set + +# +# General architecture-dependent options +# +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +CONFIG_OPTPROBES=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_KRETPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_NMI=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_RCU_TABLE_FREE=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_CC_HAS_STACKPROTECTOR_NONE=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS=8 +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OLD_SIGACTION=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_ARCH_HAS_PHYS_TO_DMA=y +CONFIG_REFCOUNT_FULL=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_PLUGIN_HOSTCC="" +CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_ZONED is not set +# CONFIG_BLK_DEV_THROTTLING is not set +# CONFIG_BLK_CMDLINE_PARSER is not set +# CONFIG_BLK_WBT is not set +# CONFIG_BLK_CGROUP_IOLATENCY is not set +CONFIG_BLK_DEBUG_FS=y +# CONFIG_BLK_SED_OPAL is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +CONFIG_BLK_MQ_PCI=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CFQ_GROUP_IOSCHED is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +CONFIG_IOSCHED_BFQ=y +# CONFIG_BFQ_GROUP_IOSCHED is not set +CONFIG_ASN1=y +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_INLINE_WRITE_UNLOCK=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_ELF_FDPIC is not set +CONFIG_ELFCORE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y + +# +# Memory Management options +# +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_BOUNCE=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +CONFIG_CMA_DEBUGFS=y +CONFIG_CMA_AREAS=7 +# CONFIG_ZSWAP is not set +# CONFIG_ZPOOL is not set +# CONFIG_ZBUD is not set +# CONFIG_ZSMALLOC is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_BENCHMARK is not set +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_TLS is not set +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +# CONFIG_XDP_SOCKETS is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=m +CONFIG_IP_MROUTE_COMMON=y +CONFIG_IP_MROUTE=y +# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_NET_FOU is not set +# CONFIG_NET_FOU_IP_TUNNELS is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TUNNEL=m +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +CONFIG_TCP_CONG_ADVANCED=y +# CONFIG_TCP_CONG_BIC is not set +CONFIG_TCP_CONG_CUBIC=y +# CONFIG_TCP_CONG_WESTWOOD is not set +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +# CONFIG_TCP_CONG_HYBLA is not set +CONFIG_TCP_CONG_VEGAS=m +# CONFIG_TCP_CONG_NV is not set +CONFIG_TCP_CONG_SCALABLE=m +# CONFIG_TCP_CONG_LP is not set +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_TCP_CONG_DCTCP is not set +CONFIG_TCP_CONG_CDG=m +# CONFIG_TCP_CONG_BBR is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_SEG6_LWTUNNEL is not set +# CONFIG_IPV6_SEG6_HMAC is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_INGRESS is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_FAMILY_BRIDGE=y +# CONFIG_NETFILTER_NETLINK_ACCT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NETFILTER_NETLINK_OSF is not set +CONFIG_NF_CONNTRACK=m +# CONFIG_NF_LOG_NETDEV is not set +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_ZONES is not set +# CONFIG_NF_CONNTRACK_PROCFS is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CONNTRACK_LABELS is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=m +# CONFIG_NF_CONNTRACK_H323 is not set +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SIP=m +# CONFIG_NF_CONNTRACK_TFTP is not set +CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +# CONFIG_NF_TABLES is not set +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +# CONFIG_NETFILTER_XT_MARK is not set +# CONFIG_NETFILTER_XT_CONNMARK is not set + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +CONFIG_NETFILTER_XT_NAT=m +# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ECN is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_NETFILTER_XT_MATCH_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +# CONFIG_NF_SOCKET_IPV4 is not set +# CONFIG_NF_TPROXY_IPV4 is not set +# CONFIG_NF_DUP_IPV4 is not set +# CONFIG_NF_LOG_ARP is not set +# CONFIG_NF_LOG_IPV4 is not set +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=y +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_RPFILTER is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_REDIRECT is not set +CONFIG_IP_NF_MANGLE=m +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_NF_SOCKET_IPV6 is not set +# CONFIG_NF_TPROXY_IPV6 is not set +# CONFIG_NF_DUP_IPV6 is not set +CONFIG_NF_REJECT_IPV6=m +# CONFIG_NF_LOG_IPV6 is not set +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_MATCH_SRH is not set +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP6_NF_RAW is not set +CONFIG_IP6_NF_NAT=m +# CONFIG_IP6_NF_TARGET_MASQUERADE is not set +# CONFIG_IP6_NF_TARGET_NPT is not set +CONFIG_NF_DEFRAG_IPV6=m +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_BPFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_BRIDGE_VLAN_FILTERING is not set +CONFIG_HAVE_NET_DSA=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_VLAN_8021Q_MVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_CBS is not set +# CONFIG_NET_SCH_ETF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_SKBPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_QFQ is not set +# CONFIG_NET_SCH_CODEL is not set +CONFIG_NET_SCH_FQ_CODEL=y +# CONFIG_NET_SCH_CAKE is not set +# CONFIG_NET_SCH_FQ is not set +# CONFIG_NET_SCH_HHF is not set +# CONFIG_NET_SCH_PIE is not set +# CONFIG_NET_SCH_PLUG is not set +# CONFIG_NET_SCH_DEFAULT is not set + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set +# CONFIG_NET_CLS_BPF is not set +# CONFIG_NET_CLS_FLOWER is not set +# CONFIG_NET_CLS_MATCHALL is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_NET_NSH is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_NET_NCSI is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +# CONFIG_BPF_STREAM_PARSER is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +CONFIG_BT=m +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=m +CONFIG_BT_HS=y +CONFIG_BT_LE=y +# CONFIG_BT_LEDS is not set +# CONFIG_BT_SELFTEST is not set +# CONFIG_BT_DEBUGFS is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m +CONFIG_BT_RTL=m +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_SERDEV=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_NOKIA is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +# CONFIG_BT_HCIUART_LL is not set +CONFIG_BT_HCIUART_3WIRE=y +# CONFIG_BT_HCIUART_INTEL is not set +CONFIG_BT_HCIUART_BCM=y +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIUART_AG6XX is not set +# CONFIG_BT_HCIUART_MRVL is not set +CONFIG_BT_HCIBCM203X=m +# CONFIG_BT_HCIBPA10X is not set +CONFIG_BT_HCIBFUSB=m +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +CONFIG_BT_ATH3K=m +# CONFIG_BT_MTKUART is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +# CONFIG_WIMAX is not set +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_PSAMPLE is not set +# CONFIG_NET_IFE is not set +# CONFIG_LWTUNNEL is not set +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +# CONFIG_NET_DEVLINK is not set +CONFIG_MAY_USE_DEVLINK=y +# CONFIG_FAILOVER is not set +CONFIG_HAVE_EBPF_JIT=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y + +# +# Generic Driver Options +# +# CONFIG_UEVENT_HELPER is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER is not set +CONFIG_WANT_DEV_COREDUMP=y +# CONFIG_ALLOW_DEV_COREDUMP is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=5 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 +CONFIG_GENERIC_ARCH_TOPOLOGY=y + +# +# Bus devices +# +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_SIMPLE_PM_BUS is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_CONNECTOR is not set +# CONFIG_GNSS is not set +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_KOBJ=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_CONFIGFS=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_CDROM=y +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=0 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +CONFIG_BLK_DEV_NBD=y +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_RSXX is not set + +# +# NVME Support +# +# CONFIG_BLK_DEV_NVME is not set +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TARGET is not set + +# +# Misc devices +# +CONFIG_BCM2835_SMI=m +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# CONFIG_PCI_ENDPOINT_TEST is not set +CONFIG_MISC_RTSX=y +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_EEPROM_IDT_89HPESX is not set +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set +# CONFIG_ALTERA_STAPL is not set + +# +# Intel MIC & related support +# + +# +# Intel MIC Bus Driver +# + +# +# SCIF Bus Driver +# + +# +# VOP Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# + +# +# SCIF Driver +# + +# +# Intel MIC Coprocessor State Management (COSM) Drivers +# + +# +# VOP Driver +# +# CONFIG_ECHO is not set +# CONFIG_MISC_RTSX_PCI is not set +CONFIG_MISC_RTSX_USB=y +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_MQ_DEFAULT is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=y +CONFIG_ISCSI_BOOT_SYSFS=y +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_SMARTPQI is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SNIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_WD719X is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set +# CONFIG_IPVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_GTP is not set +# CONFIG_MACSEC is not set +CONFIG_NETCONSOLE=y +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_TUN=y +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m +# CONFIG_NLMON is not set +# CONFIG_ARCNET is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_3COM=y +# CONFIG_VORTEX is not set +# CONFIG_TYPHOON is not set +CONFIG_NET_VENDOR_ADAPTEC=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_NET_VENDOR_AGERE=y +# CONFIG_ET131X is not set +CONFIG_NET_VENDOR_ALACRITECH=y +# CONFIG_SLICOSS is not set +CONFIG_NET_VENDOR_ALTEON=y +# CONFIG_ACENIC is not set +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMAZON=y +CONFIG_NET_VENDOR_AMD=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_PCNET32 is not set +CONFIG_NET_VENDOR_AQUANTIA=y +CONFIG_NET_VENDOR_ARC=y +CONFIG_NET_VENDOR_ATHEROS=y +# CONFIG_ATL2 is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_ALX is not set +CONFIG_NET_VENDOR_AURORA=y +# CONFIG_AURORA_NB8800 is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +CONFIG_BCMGENET=y +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2X is not set +# CONFIG_SYSTEMPORT is not set +# CONFIG_BNXT is not set +CONFIG_NET_VENDOR_BROCADE=y +# CONFIG_BNA is not set +CONFIG_NET_VENDOR_CADENCE=y +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_CAVIUM=y +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +CONFIG_NET_VENDOR_CIRRUS=y +# CONFIG_CS89x0 is not set +CONFIG_NET_VENDOR_CISCO=y +# CONFIG_ENIC is not set +CONFIG_NET_VENDOR_CORTINA=y +# CONFIG_GEMINI_ETHERNET is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +# CONFIG_NET_TULIP is not set +CONFIG_NET_VENDOR_DLINK=y +# CONFIG_DL2K is not set +# CONFIG_SUNDANCE is not set +CONFIG_NET_VENDOR_EMULEX=y +# CONFIG_BE2NET is not set +CONFIG_NET_VENDOR_EZCHIP=y +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_FARADAY=y +# CONFIG_FTMAC100 is not set +# CONFIG_FTGMAC100 is not set +CONFIG_NET_VENDOR_HISILICON=y +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HISI_FEMAC is not set +# CONFIG_HIP04_ETH is not set +# CONFIG_HNS is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +# CONFIG_HNS3 is not set +CONFIG_NET_VENDOR_HP=y +# CONFIG_HP100 is not set +CONFIG_NET_VENDOR_HUAWEI=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_ICE is not set +# CONFIG_FM10K is not set +# CONFIG_JME is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_NET_VENDOR_MELLANOX=y +# CONFIG_MLX4_EN is not set +# CONFIG_MLX5_CORE is not set +# CONFIG_MLXSW_CORE is not set +# CONFIG_MLXFW is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +# CONFIG_ENCX24J600 is not set +# CONFIG_LAN743X is not set +CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_NET_VENDOR_MYRI=y +# CONFIG_MYRI10GE is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NATSEMI=y +# CONFIG_NATSEMI is not set +# CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_NETERION=y +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +CONFIG_NET_VENDOR_NETRONOME=y +# CONFIG_NFP is not set +CONFIG_NET_VENDOR_NI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_AX88796 is not set +# CONFIG_NE2K_PCI is not set +CONFIG_NET_VENDOR_NVIDIA=y +# CONFIG_FORCEDETH is not set +CONFIG_NET_VENDOR_OKI=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PACKET_ENGINES=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_QLOGIC=y +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_QED is not set +CONFIG_NET_VENDOR_QUALCOMM=y +# CONFIG_QCA7000_SPI is not set +# CONFIG_QCA7000_UART is not set +# CONFIG_QCOM_EMAC is not set +# CONFIG_RMNET is not set +CONFIG_NET_VENDOR_RDC=y +# CONFIG_R6040 is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R8169 is not set +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_NET_VENDOR_SAMSUNG=y +# CONFIG_SXGBE_ETH is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SOLARFLARE=y +# CONFIG_SFC is not set +# CONFIG_SFC_FALCON is not set +CONFIG_NET_VENDOR_SILAN=y +# CONFIG_SC92031 is not set +CONFIG_NET_VENDOR_SIS=y +# CONFIG_SIS900 is not set +# CONFIG_SIS190 is not set +CONFIG_NET_VENDOR_SMSC=y +# CONFIG_SMC91X is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_SMSC9420 is not set +CONFIG_NET_VENDOR_SOCIONEXT=y +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_SUN=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NIU is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_DWC_XLGMAC is not set +CONFIG_NET_VENDOR_TEHUTI=y +# CONFIG_TEHUTI is not set +CONFIG_NET_VENDOR_TI=y +# CONFIG_TI_CPSW_ALE is not set +# CONFIG_TLAN is not set +CONFIG_NET_VENDOR_VIA=y +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_BCM_UNIMAC=y +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_HISI_FEMAC is not set +# CONFIG_MDIO_MSCC_MIIM is not set +CONFIG_PHYLIB=y +CONFIG_SWPHY=y +# CONFIG_LED_TRIGGER_PHY is not set + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_ASIX_PHY is not set +# CONFIG_AT803X_PHY is not set +CONFIG_BCM7XXX_PHY=y +# CONFIG_BCM87XX_PHY is not set +CONFIG_BCM_NET_PHYLIB=y +CONFIG_BROADCOM_PHY=y +# CONFIG_CICADA_PHY is not set +# CONFIG_CORTINA_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_DP83822_PHY is not set +# CONFIG_DP83TC811_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +CONFIG_FIXED_PHY=y +# CONFIG_ICPLUS_PHY is not set +# CONFIG_INTEL_XWAY_PHY is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MARVELL_10G_PHY is not set +# CONFIG_MICREL_PHY is not set +CONFIG_MICROCHIP_PHY=y +# CONFIG_MICROCHIP_T1_PHY is not set +# CONFIG_MICROSEMI_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_RENESAS_PHY is not set +# CONFIG_ROCKCHIP_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_MPPE=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_NCM is not set +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +# CONFIG_USB_NET_CDC_MBIM is not set +CONFIG_USB_NET_DM9601=y +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=y +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +CONFIG_USB_HSO=m +# CONFIG_USB_NET_INT51X1 is not set +CONFIG_USB_IPHETH=m +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +CONFIG_WLAN=y +# CONFIG_WIRELESS_WDS is not set +CONFIG_WLAN_VENDOR_ADMTEK=y +# CONFIG_ADM8211 is not set +CONFIG_ATH_COMMON=m +CONFIG_WLAN_VENDOR_ATH=y +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATH5K is not set +# CONFIG_ATH5K_PCI is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_AHB=y +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DYNACK is not set +# CONFIG_ATH9K_WOW is not set +CONFIG_ATH9K_RFKILL=y +CONFIG_ATH9K_CHANNEL_CONTEXT=y +CONFIG_ATH9K_PCOEM=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_ATH9K_HWRNG=y +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +CONFIG_CARL9170_HWRNG=y +CONFIG_ATH6KL=m +# CONFIG_ATH6KL_SDIO is not set +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_ATH6KL_TRACING is not set +CONFIG_AR5523=m +# CONFIG_WIL6210 is not set +# CONFIG_ATH10K is not set +CONFIG_WCN36XX=m +# CONFIG_WCN36XX_DEBUGFS is not set +CONFIG_WLAN_VENDOR_ATMEL=y +# CONFIG_ATMEL is not set +# CONFIG_AT76C50X_USB is not set +CONFIG_WLAN_VENDOR_BROADCOM=y +CONFIG_B43=m +CONFIG_B43_BCMA=y +CONFIG_B43_SSB=y +CONFIG_B43_BUSES_BCMA_AND_SSB=y +# CONFIG_B43_BUSES_BCMA is not set +# CONFIG_B43_BUSES_SSB is not set +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +# CONFIG_B43_SDIO is not set +CONFIG_B43_BCMA_PIO=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_G=y +CONFIG_B43_PHY_N=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_PHY_HT=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +# CONFIG_BRCMSMAC is not set +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCMFMAC_PCIE is not set +# CONFIG_BRCM_TRACING is not set +CONFIG_BRCMDBG=y +CONFIG_WLAN_VENDOR_CISCO=y +CONFIG_WLAN_VENDOR_INTEL=y +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IWL4965 is not set +# CONFIG_IWL3945 is not set +# CONFIG_IWLWIFI is not set +CONFIG_WLAN_VENDOR_INTERSIL=y +# CONFIG_HOSTAP is not set +# CONFIG_HERMES is not set +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +# CONFIG_P54_PCI is not set +# CONFIG_P54_SPI is not set +CONFIG_P54_LEDS=y +# CONFIG_PRISM54 is not set +CONFIG_WLAN_VENDOR_MARVELL=y +# CONFIG_LIBERTAS is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_MWIFIEX is not set +# CONFIG_MWL8K is not set +CONFIG_WLAN_VENDOR_MEDIATEK=y +CONFIG_MT7601U=m +CONFIG_MT76_CORE=m +CONFIG_MT76_LEDS=y +CONFIG_MT76_USB=m +CONFIG_MT76x2_COMMON=m +CONFIG_MT76x0U=m +# CONFIG_MT76x2E is not set +CONFIG_MT76x2U=m +CONFIG_WLAN_VENDOR_RALINK=y +CONFIG_RT2X00=m +# CONFIG_RT2400PCI is not set +# CONFIG_RT2500PCI is not set +# CONFIG_RT61PCI is not set +# CONFIG_RT2800PCI is not set +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WLAN_VENDOR_REALTEK=y +# CONFIG_RTL8180 is not set +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_RTL_CARDS=m +# CONFIG_RTL8192CE is not set +# CONFIG_RTL8192SE is not set +# CONFIG_RTL8192DE is not set +# CONFIG_RTL8723AE is not set +# CONFIG_RTL8723BE is not set +# CONFIG_RTL8188EE is not set +# CONFIG_RTL8192EE is not set +# CONFIG_RTL8821AE is not set +# CONFIG_RTL8192CU is not set +# CONFIG_RTL8XXXU is not set +CONFIG_WLAN_VENDOR_RSI=y +# CONFIG_RSI_91X is not set +CONFIG_WLAN_VENDOR_ST=y +# CONFIG_CW1200 is not set +CONFIG_WLAN_VENDOR_TI=y +# CONFIG_WL1251 is not set +# CONFIG_WL12XX is not set +# CONFIG_WL18XX is not set +# CONFIG_WLCORE is not set +CONFIG_WLAN_VENDOR_ZYDAS=y +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_USB_NET_RNDIS_WLAN=m + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_VMXNET3 is not set +# CONFIG_NETDEVSIM is not set +# CONFIG_NET_FAILOVER is not set +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=m +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_MATRIXKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_DLINK_DIR685 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=m +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_PSXPAD_SPI=m +CONFIG_JOYSTICK_PSXPAD_SPI_FF=y +# CONFIG_JOYSTICK_PXRC is not set +# CONFIG_JOYSTICK_RPISENSE is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TOUCHSCREEN_ADS7846=m +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_BU21029 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +CONFIG_TOUCHSCREEN_EGALAX=m +# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set +# CONFIG_TOUCHSCREEN_EXC3000 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_HIDEEP is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_S6SY761 is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_EKTF2127 is not set +# CONFIG_TOUCHSCREEN_ELAN is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +CONFIG_TOUCHSCREEN_RPI_FT5406=m +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +# CONFIG_TOUCHSCREEN_USB_PANJIT is not set +CONFIG_TOUCHSCREEN_USB_3M=y +# CONFIG_TOUCHSCREEN_USB_ITM is not set +# CONFIG_TOUCHSCREEN_USB_ETURBO is not set +# CONFIG_TOUCHSCREEN_USB_GUNZE is not set +# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set +# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set +# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set +# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set +# CONFIG_TOUCHSCREEN_USB_GOTOP is not set +# CONFIG_TOUCHSCREEN_USB_JASTEC is not set +# CONFIG_TOUCHSCREEN_USB_ELO is not set +# CONFIG_TOUCHSCREEN_USB_E2I is not set +# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set +# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set +# CONFIG_TOUCHSCREEN_USB_NEXIO is not set +# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2004 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_RM_TS is not set +# CONFIG_TOUCHSCREEN_SILEAD is not set +# CONFIG_TOUCHSCREEN_SIS_I2C is not set +CONFIG_TOUCHSCREEN_ST1232=m +# CONFIG_TOUCHSCREEN_STMFTS is not set +# CONFIG_TOUCHSCREEN_SUR40 is not set +# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set +# CONFIG_TOUCHSCREEN_SX8654 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_ZET6223 is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ARIZONA_HAPTICS is not set +# CONFIG_INPUT_ATMEL_CAPTOUCH is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_DECODER is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_PWM_VIBRA is not set +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set +CONFIG_RMI4_CORE=y +# CONFIG_RMI4_I2C is not set +# CONFIG_RMI4_SPI is not set +# CONFIG_RMI4_SMB is not set +CONFIG_RMI4_F03=y +CONFIG_RMI4_F03_SERIO=y +CONFIG_RMI4_2D_SENSOR=y +CONFIG_RMI4_F11=y +CONFIG_RMI4_F12=y +CONFIG_RMI4_F30=y +# CONFIG_RMI4_F34 is not set +# CONFIG_RMI4_F55 is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_SERIO_GPIO_PS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_BRCM_CHAR_DRIVERS=y +CONFIG_BCM2708_VCMEM=y +CONFIG_BCM_VCIO=y +CONFIG_BCM_VC_SM=y +CONFIG_BCM2835_DEVGPIOMEM=m +CONFIG_BCM2835_SMI_DEV=m +CONFIG_ARGON_MEM=m +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_LDISC_AUTOLOAD=y +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +# CONFIG_SERIAL_8250_FINTEK is not set +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_EXAR=y +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_ASPEED_VUART is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set +CONFIG_SERIAL_8250_BCM2835AUX=y +CONFIG_SERIAL_8250_FSL=y +# CONFIG_SERIAL_8250_DW is not set +# CONFIG_SERIAL_8250_EM is not set +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_MOXA is not set +CONFIG_SERIAL_OF_PLATFORM=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_BCM63XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_ST_ASC is not set +CONFIG_SERIAL_DEV_BUS=m +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_BCM2835=y +CONFIG_HW_RANDOM_IPROC_RNG200=y +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_XILLYBUS is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=m + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +# CONFIG_I2C_DEMUX_PINCTRL is not set +# CONFIG_I2C_MUX_MLXCPLD is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_BCM2708=y +CONFIG_I2C_BCM2708_BAUDRATE=100000 +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_BCM2835=m +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EMEV2 is not set +CONFIG_I2C_GPIO=y +# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_RK3X is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +# CONFIG_SPI_MEM is not set + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +CONFIG_SPI_BCM2835=m +CONFIG_SPI_BCM2835AUX=m +# CONFIG_SPI_BCM_QSPI is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_DESIGNWARE is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_ROCKCHIP is not set +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_LOOPBACK_TEST is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_SLAVE is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set +# CONFIG_PPS is not set + +# +# PTP clock support +# +# CONFIG_PTP_1588_CLOCK is not set + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_AMD is not set +# CONFIG_PINCTRL_MCP23S08 is not set +# CONFIG_PINCTRL_SINGLE is not set +# CONFIG_PINCTRL_SX150X is not set +CONFIG_PINCTRL_BCM2835=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_OF_GPIO=y +CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +CONFIG_GPIO_RASPBERRYPI_EXP=y +CONFIG_GPIO_BCM_VIRT=y +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_EXAR is not set +# CONFIG_GPIO_FTGPIO010 is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_HLWD is not set +# CONFIG_GPIO_MB86S7X is not set +# CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_MPC8XXX is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_SYSCON is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZEVIO is not set + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TPIC2810 is not set + +# +# MFD GPIO expanders +# +CONFIG_GPIO_ARIZONA=m +# CONFIG_HTC_EGPIO is not set + +# +# PCI GPIO expanders +# +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_PCI_IDIO_16 is not set +# CONFIG_GPIO_PCIE_IDIO_24 is not set +# CONFIG_GPIO_RDC321X is not set + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX3191X is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_PISOSR is not set +# CONFIG_GPIO_XRA1403 is not set + +# +# USB GPIO expanders +# +CONFIG_W1=m + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_MATROX is not set +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2405 is not set +# CONFIG_W1_SLAVE_DS2408 is not set +# CONFIG_W1_SLAVE_DS2413 is not set +# CONFIG_W1_SLAVE_DS2406 is not set +# CONFIG_W1_SLAVE_DS2423 is not set +# CONFIG_W1_SLAVE_DS2805 is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2438 is not set +# CONFIG_W1_SLAVE_DS2780 is not set +# CONFIG_W1_SLAVE_DS2781 is not set +# CONFIG_W1_SLAVE_DS28E04 is not set +# CONFIG_W1_SLAVE_DS28E17 is not set +# CONFIG_POWER_AVS is not set +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_BRCMKONA is not set +# CONFIG_POWER_RESET_BRCMSTB is not set +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_POWER_RESET_LTC2952 is not set +CONFIG_POWER_RESET_RESTART=y +# CONFIG_POWER_RESET_VERSATILE is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +# CONFIG_SYSCON_REBOOT_MODE is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_CHARGER_ADP5061 is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_CHARGER_SBS is not set +# CONFIG_MANAGER_SBS is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_MAX1721X is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_LTC3651 is not set +# CONFIG_CHARGER_DETECTOR_MAX14656 is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_CHARGER_RT9455 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ASPEED is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FTSTEUTATES is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC2990 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX31722 is not set +# CONFIG_SENSORS_MAX6621 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_NPCM7XX is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_PWM_FAN is not set +CONFIG_SENSORS_RASPBERRYPI_HWMON=y +CONFIG_SENSORS_RPI_POE_FAN=m +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHT3x is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_STTS751 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA3221 is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP108 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83773G is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +# CONFIG_THERMAL_STATISTICS is not set +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +# CONFIG_CPU_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_QORIQ_THERMAL is not set + +# +# ACPI INT340X thermal drivers +# + +# +# Broadcom thermal drivers +# +CONFIG_BCM2835_THERMAL=y +CONFIG_BRCMSTB_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +# CONFIG_WATCHDOG_SYSFS is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_FTWDT010_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_I6300ESB_WDT is not set +CONFIG_BCM2835_WDT=y +# CONFIG_MEN_A21_WDT is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Watchdog Pretimeout Governors +# +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +# CONFIG_SSB_SDIOHOST is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_GPIO is not set +CONFIG_BCMA_POSSIBLE=y +CONFIG_BCMA=m +CONFIG_BCMA_BLOCKIO=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +CONFIG_BCMA_HOST_PCI=y +# CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMA_DRIVER_PCI=y +CONFIG_BCMA_DRIVER_GMAC_CMN=y +# CONFIG_BCMA_DRIVER_GPIO is not set +# CONFIG_BCMA_DEBUG is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_RPISENSE_CORE is not set +# CONFIG_MFD_ACT8945A is not set +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AXP20X_I2C is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_MFD_MADERA is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77620 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_CPCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_PM8XXX is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RK808 is not set +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MFD_VX855 is not set +CONFIG_MFD_ARIZONA=y +CONFIG_MFD_ARIZONA_I2C=m +CONFIG_MFD_ARIZONA_SPI=m +# CONFIG_MFD_CS47L24 is not set +CONFIG_MFD_WM5102=y +# CONFIG_MFD_WM5110 is not set +# CONFIG_MFD_WM8997 is not set +# CONFIG_MFD_WM8998 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_ROHM_BD718XX is not set +# CONFIG_RAVE_SP_CORE is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=m +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_88PG86X is not set +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ANATOP is not set +CONFIG_REGULATOR_ARIZONA_LDO1=m +CONFIG_REGULATOR_ARIZONA_MICSUPP=m +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +# CONFIG_REGULATOR_FAN53555 is not set +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_LTC3676 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set +# CONFIG_REGULATOR_PV88090 is not set +# CONFIG_REGULATOR_PWM is not set +# CONFIG_REGULATOR_SY8106A is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_VCTRL is not set +CONFIG_RC_CORE=m +CONFIG_RC_MAP=m +CONFIG_LIRC=y +CONFIG_RC_DECODERS=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_RCMM_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +# CONFIG_IR_HIX5HD2 is not set +CONFIG_IR_IMON=m +CONFIG_IR_IMON_RAW=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_REDRAT3=m +# CONFIG_IR_SPI is not set +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGORPLUGUSB=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +# CONFIG_RC_LOOPBACK is not set +CONFIG_IR_GPIO_CIR=m +CONFIG_IR_GPIO_TX=m +CONFIG_IR_PWM_TX=m +# CONFIG_IR_SERIAL is not set +# CONFIG_IR_SIR is not set +CONFIG_RC_XBOX_DVD=m +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +# CONFIG_MEDIA_SDR_SUPPORT is not set +# CONFIG_MEDIA_CEC_SUPPORT is not set +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2=m +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_PCI_SKELETON is not set +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_DVB_CORE=m +# CONFIG_DVB_MMAP is not set +CONFIG_DVB_NET=y +CONFIG_TTPCI_EEPROM=m +CONFIG_DVB_MAX_ADAPTERS=8 +# CONFIG_DVB_DYNAMIC_MINORS is not set +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set +# CONFIG_DVB_ULE_DEBUG is not set + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +# CONFIG_USB_VIDEO_CLASS is not set +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_VIDEO_USBTV=m + +# +# Analog TV USB devices +# +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_STK1160=m +# CONFIG_VIDEO_GO7007 is not set + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y +CONFIG_VIDEO_AU0828_RC=y +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_RC=y +# CONFIG_VIDEO_CX231XX_ALSA is not set +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +# CONFIG_VIDEO_TM6000_ALSA is not set +CONFIG_VIDEO_TM6000_DVB=m + +# +# Digital TV USB devices +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB3000MC=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_DVB_USB_ZD1301=m +# CONFIG_DVB_TTUSB_BUDGET is not set +# CONFIG_DVB_TTUSB_DEC is not set +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set +CONFIG_DVB_AS102=m + +# +# Webcam, TV (analog/digital) USB devices +# +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_EM28XX_V4L2 is not set +# CONFIG_VIDEO_EM28XX_ALSA is not set +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_EM28XX_RC=m +# CONFIG_MEDIA_PCI_SUPPORT is not set +# CONFIG_V4L_PLATFORM_DRIVERS is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_DVB_PLATFORM_DRIVERS is not set + +# +# Supported MMC/SDIO adapters +# +CONFIG_SMS_SDIO_DRV=m +# CONFIG_RADIO_ADAPTERS is not set +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_V4L2=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y +# CONFIG_SMS_SIANO_DEBUGFS is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) +# +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_ATTACH=y +CONFIG_VIDEO_IR_I2C=m + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m + +# +# RDS decoders +# + +# +# Video decoders +# +CONFIG_VIDEO_SAA711X=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_CX25840=m + +# +# Video encoders +# + +# +# Camera sensor devices +# + +# +# Flash devices +# + +# +# Video improvement chips +# + +# +# Audio/Video compression chips +# + +# +# SDR tuner chips +# + +# +# Miscellaneous helper chips +# + +# +# Sensors used on soc_camera driver +# + +# +# Media SPI Adapters +# +CONFIG_CXD2880_SPI_DRV=m +CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18250=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_TUA9001=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_R820T=m +CONFIG_MEDIA_TUNER_QM1D1C0042=m + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV6110x=m +CONFIG_DVB_M88DS3103=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_TDA18271C2DD=m +CONFIG_DVB_SI2165=m +CONFIG_DVB_MN88472=m +CONFIG_DVB_MN88473=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24120=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_TS2020=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_TDA10071=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_CX22702=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_AS102_FE=m +CONFIG_DVB_ZD1301_DEMOD=m +CONFIG_DVB_GP8PSK_FE=m +CONFIG_DVB_CXD2880=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LGDT3306A=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_S921=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_MB86A20S=m + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# +CONFIG_DVB_TC90522=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_DRX39XYJ=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_A8293=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_M88RS2000=m +CONFIG_DVB_AF9033=m + +# +# Common Interface (EN50221) controller drivers +# +CONFIG_DVB_SP2=m + +# +# Tools to develop new frontends +# + +# +# Graphics support +# +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +# CONFIG_IMX_IPUV3_CORE is not set +CONFIG_DRM=y +CONFIG_DRM_MIPI_DSI=y +# CONFIG_DRM_DP_AUX_CHARDEV is not set +# CONFIG_DRM_DEBUG_MM is not set +# CONFIG_DRM_DEBUG_SELFTEST is not set +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=100 +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +# CONFIG_DRM_DP_CEC is not set +CONFIG_DRM_GEM_CMA_HELPER=y +CONFIG_DRM_KMS_CMA_HELPER=y +CONFIG_DRM_SCHED=y + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_I2C_NXP_TDA9950 is not set +# CONFIG_DRM_HDLCD is not set +# CONFIG_DRM_MALI_DISPLAY is not set +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_AMDGPU is not set + +# +# ACP (Audio CoProcessor) Configuration +# + +# +# AMD Library routines +# +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VKMS is not set +# CONFIG_DRM_EXYNOS is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_AST is not set +# CONFIG_DRM_MGAG200 is not set +# CONFIG_DRM_CIRRUS_QEMU is not set +# CONFIG_DRM_ARMADA is not set +# CONFIG_DRM_RCAR_DW_HDMI is not set +# CONFIG_DRM_RCAR_LVDS is not set +# CONFIG_DRM_OMAP is not set +# CONFIG_DRM_TILCDC is not set +# CONFIG_DRM_QXL is not set +# CONFIG_DRM_BOCHS is not set +# CONFIG_DRM_FSL_DCU is not set +# CONFIG_DRM_STM is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +# CONFIG_DRM_PANEL_ARM_VERSATILE is not set +# CONFIG_DRM_PANEL_LVDS is not set +# CONFIG_DRM_PANEL_SIMPLE is not set +# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set +# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set +# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set +# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set +# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set +# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set +# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PANEL_BRIDGE=y + +# +# Display Interface Bridges +# +# CONFIG_DRM_ANALOGIX_ANX78XX is not set +# CONFIG_DRM_CDNS_DSI is not set +# CONFIG_DRM_DUMB_VGA_DAC is not set +# CONFIG_DRM_LVDS_ENCODER is not set +# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_SIL_SII8620 is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SII9234 is not set +# CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358767 is not set +# CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_STI is not set +CONFIG_DRM_V3D=y +CONFIG_DRM_VC4=y +# CONFIG_DRM_VC4_HDMI_CEC is not set +# CONFIG_DRM_ARCPGU is not set +# CONFIG_DRM_HISI_HIBMC is not set +# CONFIG_DRM_MXSFB is not set +# CONFIG_DRM_TINYDRM is not set +# CONFIG_DRM_PL111 is not set +# CONFIG_DRM_TVE200 is not set +# CONFIG_DRM_LEGACY is not set +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CMDLINE=y +CONFIG_FB_NOTIFY=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_BCM2708=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +# CONFIG_FB_SM712 is not set +# CONFIG_FB_RPISENSE is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_L4F00242T03 is not set +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_ILI922X is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +# CONFIG_LCD_PLATFORM is not set +# CONFIG_LCD_S6E63M0 is not set +# CONFIG_LCD_LD9040 is not set +# CONFIG_LCD_AMS369FG06 is not set +# CONFIG_LCD_LMS501KF03 is not set +# CONFIG_LCD_HX8357 is not set +# CONFIG_LCD_OTM3225A is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set +# CONFIG_BACKLIGHT_PWM is not set +CONFIG_BACKLIGHT_RPI=y +# CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +CONFIG_BACKLIGHT_GPIO=y +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set +# CONFIG_BACKLIGHT_ARCXCNN is not set +CONFIG_HDMI=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_PCM_ELD=y +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_COMPRESS_OFFLOAD=y +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +# CONFIG_SND_OSSEMUL is not set +CONFIG_SND_PCM_TIMER=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SE6X is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# HD-Audio +# +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_HDA_PREALLOC_SIZE=2048 +CONFIG_SND_ARM=y +# CONFIG_SND_ARMAACI is not set +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_USB_HIFACE=m +CONFIG_SND_BCD2000=m +CONFIG_SND_USB_LINE6=m +CONFIG_SND_USB_POD=m +CONFIG_SND_USB_PODHD=m +CONFIG_SND_USB_TONEPORT=m +CONFIG_SND_USB_VARIAX=m +CONFIG_SND_SOC=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +CONFIG_SND_SOC_COMPRESS=y +# CONFIG_SND_SOC_AMD_ACP is not set +# CONFIG_SND_ATMEL_SOC is not set +CONFIG_SND_BCM2835_SOC_I2S=m +CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m +CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m +CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +CONFIG_SND_BCM2708_SOC_RPI_DAC=m +CONFIG_SND_BCM2708_SOC_RPI_PROTO=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m +CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m +CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m +CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m +CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m +CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m +CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +CONFIG_SND_AUDIOSENSE_PI=m +CONFIG_SND_DIGIDAC1_SOUNDCARD=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m +CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m +CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m +CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m +CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m +CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m +CONFIG_SND_PISOUND=m +CONFIG_SND_RPI_SIMPLE_SOUNDCARD=m +CONFIG_SND_RPI_WM8804_SOUNDCARD=m +# CONFIG_SND_DESIGNWARE_I2S is not set + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_I2S_HI6210_I2S is not set +# CONFIG_SND_SOC_IMG is not set + +# +# STMicroelectronics STM32 SOC audio support +# +# CONFIG_SND_SOC_XTFPGA_I2S is not set +# CONFIG_ZX_TDM is not set +CONFIG_SND_SOC_I2C_AND_SPI=y + +# +# CODEC drivers +# +CONFIG_SND_SOC_ARIZONA=m +CONFIG_SND_SOC_WM_ADSP=m +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_AD193X_SPI is not set +# CONFIG_SND_SOC_AD193X_I2C is not set +CONFIG_SND_SOC_ADAU1701=m +# CONFIG_SND_SOC_ADAU1761_I2C is not set +# CONFIG_SND_SOC_ADAU1761_SPI is not set +CONFIG_SND_SOC_ADAU1977=m +CONFIG_SND_SOC_ADAU1977_I2C=m +CONFIG_SND_SOC_ADAU7002=m +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4458 is not set +CONFIG_SND_SOC_AK4554=m +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_AK5558 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_BD28623 is not set +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS35L33 is not set +# CONFIG_SND_SOC_CS35L34 is not set +# CONFIG_SND_SOC_CS35L35 is not set +# CONFIG_SND_SOC_CS42L42 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +CONFIG_SND_SOC_CS4265=m +# CONFIG_SND_SOC_CS4270 is not set +CONFIG_SND_SOC_CS4271=m +CONFIG_SND_SOC_CS4271_I2C=m +# CONFIG_SND_SOC_CS4271_SPI is not set +CONFIG_SND_SOC_CS42XX8=m +CONFIG_SND_SOC_CS42XX8_I2C=m +# CONFIG_SND_SOC_CS43130 is not set +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CS53L30 is not set +CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DMIC=m +# CONFIG_SND_SOC_ES7134 is not set +# CONFIG_SND_SOC_ES7241 is not set +# CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_ES8328_I2C is not set +# CONFIG_SND_SOC_ES8328_SPI is not set +# CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_ICS43432 is not set +# CONFIG_SND_SOC_INNO_RK3036 is not set +# CONFIG_SND_SOC_MAX98504 is not set +# CONFIG_SND_SOC_MAX9867 is not set +# CONFIG_SND_SOC_MAX98927 is not set +# CONFIG_SND_SOC_MAX98373 is not set +# CONFIG_SND_SOC_MAX9860 is not set +# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1789_I2C is not set +# CONFIG_SND_SOC_PCM179X_I2C is not set +# CONFIG_SND_SOC_PCM179X_SPI is not set +# CONFIG_SND_SOC_PCM186X_I2C is not set +# CONFIG_SND_SOC_PCM186X_SPI is not set +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_PCM3168A_SPI is not set +CONFIG_SND_SOC_PCM5102A=m +CONFIG_SND_SOC_PCM512x=m +CONFIG_SND_SOC_PCM512x_I2C=m +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_RT5616 is not set +CONFIG_SND_SOC_PCM1794A=m +# CONFIG_SND_SOC_RT5631 is not set +CONFIG_SND_SOC_SGTL5000=m +CONFIG_SND_SOC_SIGMADSP=m +CONFIG_SND_SOC_SIGMADSP_I2C=m +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +CONFIG_SND_SOC_SPDIF=m +# CONFIG_SND_SOC_SSM2305 is not set +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +CONFIG_SND_SOC_STA32X=m +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TAS5720 is not set +# CONFIG_SND_SOC_TAS6424 is not set +# CONFIG_SND_SOC_TDA7419 is not set +# CONFIG_SND_SOC_TFA9879 is not set +CONFIG_SND_SOC_TAS5713=m +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +CONFIG_SND_SOC_TLV320AIC32X4=m +CONFIG_SND_SOC_TLV320AIC32X4_I2C=m +# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +# CONFIG_SND_SOC_TS3A227E is not set +# CONFIG_SND_SOC_TSCS42XX is not set +# CONFIG_SND_SOC_TSCS454 is not set +CONFIG_SND_SOC_WM5102=m +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8524 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +CONFIG_SND_SOC_WM8731=m +# CONFIG_SND_SOC_WM8737 is not set +CONFIG_SND_SOC_WM8741=m +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8782 is not set +CONFIG_SND_SOC_WM8804=m +CONFIG_SND_SOC_WM8804_I2C=m +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8960 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8974 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_WM8985 is not set +# CONFIG_SND_SOC_ZX_AUD96P22 is not set +# CONFIG_SND_SOC_MAX9759 is not set +# CONFIG_SND_SOC_MT6351 is not set +# CONFIG_SND_SOC_NAU8540 is not set +# CONFIG_SND_SOC_NAU8810 is not set +# CONFIG_SND_SOC_NAU8824 is not set +CONFIG_SND_SOC_TPA6130A2=m +CONFIG_SND_SOC_I_SABRE_CODEC=m +CONFIG_SND_SIMPLE_CARD_UTILS=m +CONFIG_SND_SIMPLE_CARD=m +# CONFIG_SND_SIMPLE_SCU_CARD is not set +CONFIG_SND_AUDIO_GRAPH_CARD=m +# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +# CONFIG_HID_ACCUTOUCH is not set +# CONFIG_HID_ACRUX is not set +CONFIG_HID_APPLE=y +# CONFIG_HID_APPLEIR is not set +CONFIG_HID_ASUS=y +CONFIG_HID_AUREAL=y +CONFIG_HID_BELKIN=y +# CONFIG_HID_BETOP_FF is not set +CONFIG_HID_BIGBEN_FF=m +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_COUGAR is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CMEDIA is not set +# CONFIG_HID_CP2112 is not set +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELAN is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +CONFIG_HID_EZKEY=y +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GOOGLE_HAMMER is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_KEYTOUCH is not set +CONFIG_HID_KYE=y +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +CONFIG_HID_GYRATION=y +# CONFIG_HID_ICADE is not set +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +CONFIG_HID_TWINHAN=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LCPOWER=y +# CONFIG_HID_LED is not set +CONFIG_HID_LENOVO=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH_DJ=y +CONFIG_HID_LOGITECH_HIDPP=y +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_REDRAGON is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_MULTITOUCH=m +# CONFIG_HID_NTI is not set +# CONFIG_HID_NTRIG is not set +CONFIG_HID_ORTEK=y +CONFIG_HID_OUYA=y +CONFIG_HID_PANTHERLORD=y +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PENMOUNT=y +CONFIG_HID_PETALYNX=y +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_RETRODE is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_SONY_FF=y +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEAM is not set +# CONFIG_HID_STEELSERIES is not set +CONFIG_HID_SUNPLUS=y +CONFIG_HID_RMI=y +# CONFIG_HID_GREENASIA is not set +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=y +CONFIG_HID_TOPSEED=y +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_UDRAW_PS3 is not set +# CONFIG_HID_WACOM is not set +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=y +# CONFIG_HID_ZEROPLUS is not set +CONFIG_HID_ZYDACRON=y +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_ALPS is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +# CONFIG_I2C_HID is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_PCI=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set +CONFIG_USB_MON=m +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +# CONFIG_USB_XHCI_DBGCAP is not set +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_XHCI_PLATFORM=y +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_DWCOTG=y +# CONFIG_USB_HCD_BCMA is not set +# CONFIG_USB_HCD_SSB is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_UAS=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=m +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_F8153X is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +CONFIG_USB_SERIAL_IUU=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MXUPORT is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_UPD78F0730 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_HUB_USB251XB is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +# CONFIG_USB_GADGET is not set +# CONFIG_TYPEC is not set +# CONFIG_USB_ROLE_SWITCH is not set +# CONFIG_USB_LED_TRIG is not set +# CONFIG_USB_ULPI_BUS is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SIMPLE=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_BCM2835_MMC=y +CONFIG_MMC_BCM2835_DMA=y +CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 +CONFIG_MMC_BCM2835_SDHOST=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set +# CONFIG_MMC_SDHCI_CADENCE is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set +CONFIG_MMC_SDHCI_IPROC=y +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_DW is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +CONFIG_MMC_REALTEK_USB=m +# CONFIG_MMC_CQHCI is not set +# CONFIG_MMC_TOSHIBA_PCI is not set +# CONFIG_MMC_BCM2835 is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MMC_SDHCI_XENON is not set +# CONFIG_MMC_SDHCI_OMAP is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=y +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set + +# +# LED drivers +# +# CONFIG_LEDS_AAT1290 is not set +# CONFIG_LEDS_AS3645A is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_CR0014114 is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_LM3692X is not set +# CONFIG_LEDS_LM3601X is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_KTD2692 is not set +# CONFIG_LEDS_IS31FL319X is not set +# CONFIG_LEDS_IS31FL32XX is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_SYSCON is not set +# CONFIG_LEDS_MLXREG is not set +# CONFIG_LEDS_USER is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +# CONFIG_LEDS_TRIGGER_ACTIVITY is not set +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=y +CONFIG_LEDS_TRIGGER_CAMERA=y +CONFIG_LEDS_TRIGGER_INPUT=y +# CONFIG_LEDS_TRIGGER_PANIC is not set +# CONFIG_LEDS_TRIGGER_NETDEV is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_DS1307=m +# CONFIG_RTC_DRV_DS1307_CENTURY is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12026 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_DRV_PCF8523=m +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +CONFIG_RTC_DRV_PCF8563=m +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV8803 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1302 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_RX6110 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_MCP795 is not set +CONFIG_RTC_I2C_AND_SPI=y + +# +# SPI and I2C RTC drivers +# +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_DS3232_HWMON=y +CONFIG_RTC_DRV_PCF2127=m +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_FTRTC010 is not set +# CONFIG_RTC_DRV_SNVS is not set +# CONFIG_RTC_DRV_R7301 is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DMA_OF=y +# CONFIG_ALTERA_MSGDMA is not set +# CONFIG_AMBA_PL08X is not set +CONFIG_DMA_BCM2835=y +# CONFIG_DW_AXI_DMAC is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_NBPFAXI_DMA is not set +# CONFIG_PL330_DMA is not set +CONFIG_DMA_BCM2708=y +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y +# CONFIG_SW_SYNC is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_VIRTIO_MENU is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_RTL8192U is not set +# CONFIG_RTLLIB is not set +CONFIG_RTL8723BS=m +CONFIG_R8712U=m +# CONFIG_R8188EU is not set +# CONFIG_R8822BE is not set +# CONFIG_RTS5208 is not set +# CONFIG_VT6655 is not set +CONFIG_VT6656=m +# CONFIG_FB_SM750 is not set +# CONFIG_FB_XGI is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +CONFIG_STAGING_MEDIA=y + +# +# Android +# +# CONFIG_STAGING_BOARD is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_DGNC is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_UNISYSSPAR is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +# CONFIG_FB_TFT is not set +# CONFIG_WILC1000_SDIO is not set +# CONFIG_WILC1000_SPI is not set +# CONFIG_MOST is not set +# CONFIG_KS7010 is not set +# CONFIG_GREYBUS is not set +CONFIG_BCM_VIDEOCORE=y +CONFIG_BCM2835_VCHIQ=y +CONFIG_SND_BCM2835=m +# CONFIG_VIDEO_BCM2835 is not set +CONFIG_BCM2835_VCHIQ_MMAL=m +CONFIG_BCM_VC_SM_CMA=y +CONFIG_VIDEO_CODEC_BCM2835=m +# CONFIG_PI433 is not set +# CONFIG_MTK_MMC is not set + +# +# Gasket devices +# +# CONFIG_XIL_AXIS_FIFO is not set +# CONFIG_EROFS_FS is not set +# CONFIG_GOLDFISH is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_CLK_HSDK is not set +# CONFIG_COMMON_CLK_MAX9485 is not set +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI544 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE706 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_COMMON_CLK_CS2000_CP is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_PWM is not set +# CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_CLKSRC_MMIO=y +CONFIG_BCM2835_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_TIMER_SP804=y +CONFIG_MAILBOX=y +# CONFIG_ARM_MHU is not set +# CONFIG_PLATFORM_MHU is not set +# CONFIG_PL320_MBOX is not set +# CONFIG_ALTERA_MBOX is not set +CONFIG_BCM2835_MBOX=y +# CONFIG_MAILBOX_TEST is not set +# CONFIG_IOMMU_SUPPORT is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set + +# +# Rpmsg drivers +# +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set +# CONFIG_RPMSG_VIRTIO is not set +# CONFIG_SOUNDWIRE is not set + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# + +# +# Broadcom SoC drivers +# +CONFIG_BCM2835_POWER=y +CONFIG_RASPBERRYPI_POWER=y +# CONFIG_SOC_BRCMSTB is not set + +# +# NXP/Freescale QorIQ SoC drivers +# + +# +# i.MX SoC drivers +# + +# +# Qualcomm SoC drivers +# +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# CONFIG_XILINX_VCU is not set +# CONFIG_PM_DEVFREQ is not set +CONFIG_EXTCON=m + +# +# Extcon Device Drivers +# +CONFIG_EXTCON_ARIZONA=m +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_MAX3355 is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_VME_BUS is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +CONFIG_PWM_BCM2835=m +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set + +# +# IRQ chip support +# +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_MAX_NR=1 +# CONFIG_IPACK_BUS is not set +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_TI_SYSCON is not set +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +# CONFIG_GENERIC_PHY is not set +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_MAPPHONE_MDM6600 is not set +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# CONFIG_ARM_CCI_PMU is not set +# CONFIG_ARM_CCN is not set +CONFIG_ARM_PMU=y +CONFIG_RPI_AXIPERF=m +# CONFIG_RAS is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_LIBNVDIMM is not set +# CONFIG_DAX is not set +CONFIG_NVMEM=y + +# +# HW tracing support +# +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# CONFIG_FPGA is not set +# CONFIG_FSI is not set +# CONFIG_TEE is not set +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_FS_IOMAP=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_ENCRYPTION is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_ONLINE_SCRUB is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_BTRFS_FS=m +# CONFIG_BTRFS_FS_POSIX_ACL is not set +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_BTRFS_FS_REF_VERIFY is not set +# CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_F2FS_FS_XATTR is not set +CONFIG_F2FS_CHECK_FS=y +# CONFIG_F2FS_IO_TRACE is not set +# CONFIG_F2FS_FAULT_INJECTION is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_FILE_LOCKING=y +CONFIG_MANDATORY_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_AUTOFS4_FS=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set +CONFIG_OVERLAY_FS=m +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y +# CONFIG_OVERLAY_FS_INDEX is not set +# CONFIG_OVERLAY_FS_XINO_AUTO is not set +# CONFIG_OVERLAY_FS_METACOPY is not set + +# +# Caches +# +CONFIG_FSCACHE=y +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +# CONFIG_CACHEFILES is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_FAT_DEFAULT_UTF8 is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLBFS is not set +CONFIG_MEMFD_CREATE=y +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ORANGEFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=y +CONFIG_HFSPLUS_FS=y +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_FLEXFILE_LAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +CONFIG_NFS_V4_1_MIGRATION=y +CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFSD is not set +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_FSCACHE=y +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEY_DH_OPERATIONS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_FORTIFY_SOURCE is not set +# CONFIG_STATIC_USERMODEHELPER is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=m +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_RSA=y +# CONFIG_CRYPTO_DH is not set +CONFIG_CRYPTO_ECDH=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=m +# CONFIG_CRYPTO_MCRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_SIMD=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=m +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +# CONFIG_CRYPTO_AEGIS128 is not set +# CONFIG_CRYPTO_AEGIS128L is not set +# CONFIG_CRYPTO_AEGIS256 is not set +# CONFIG_CRYPTO_MORUS640 is not set +# CONFIG_CRYPTO_MORUS1280 is not set +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_ECHAINIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CFB=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_KEYWRAP is not set + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=y +# CONFIG_CRYPTO_CRCT10DIF is not set +CONFIG_CRYPTO_GHASH=m +# CONFIG_CRYPTO_POLY1305 is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_SHA3 is not set +# CONFIG_CRYPTO_SM3 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_AES_TI is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_SM4 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +CONFIG_CRYPTO_LZO=m +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set +# CONFIG_CRYPTO_ZSTD is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +# CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_HASH_INFO=y +# CONFIG_CRYPTO_HW is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set + +# +# Certificates for signature checking +# +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set +# CONFIG_SECONDARY_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_RATIONAL=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC64 is not set +# CONFIG_CRC4 is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +# CONFIG_CRC8 is not set +CONFIG_XXHASH=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_COMPRESS=m +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SGL_ALLOC=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_CLZ_TAB=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +# CONFIG_IRQ_POLL is not set +CONFIG_MPILIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_SG_POOL=y +CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_SBITMAP=y +# CONFIG_STRING_SELFTEST is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_DYNAMIC_DEBUG=y + +# +# Compile-time checks and compiler options +# +# CONFIG_DEBUG_INFO is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_PAGE_REF is not set +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +# CONFIG_SOFTLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_WQ_WATCHDOG is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +CONFIG_TRACE_IRQFLAGS=y +CONFIG_STACKTRACE=y +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set + +# +# RCU Debugging +# +# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_PREEMPTIRQ_TRACEPOINTS=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_PREEMPTIRQ_EVENTS is not set +CONFIG_IRQSOFF_TRACER=y +CONFIG_SCHED_TRACER=y +# CONFIG_HWLAT_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +CONFIG_TRACER_SNAPSHOT=y +CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_KPROBE_EVENTS=y +# CONFIG_UPROBE_EVENTS is not set +CONFIG_BPF_EVENTS=y +CONFIG_PROBE_EVENTS=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_TRACE_EVAL_MAP_FILE is not set +CONFIG_TRACING_EVENTS_GPIO=y +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +# CONFIG_MEMTEST is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_UBSAN is not set +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_ARM_PTDUMP_DEBUGFS is not set +# CONFIG_DEBUG_WX is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_OLD_MCOUNT=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_LL is not set +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +# CONFIG_ARM_KPROBES_TEST is not set +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_CORESIGHT is not set diff --git a/projects/RPi/devices/RPi4/options b/projects/RPi/devices/RPi4/options new file mode 100644 index 0000000000..6ddbf5a871 --- /dev/null +++ b/projects/RPi/devices/RPi4/options @@ -0,0 +1,14 @@ +################################################################################ +# Device defaults +################################################################################ + + # NOOBS supported hex versions (legacy) + NOOBS_HEX="1040,1041,2082" + + # NOOBS supported model versions + NOOBS_SUPPORTED_MODELS='"Pi 4"' + + OPENGLES="mesa" + GRAPHIC_DRIVERS="vc4" + KODIPLAYER_DRIVER="mesa" + unset KODI_VENDOR diff --git a/projects/RPi/devices/RPi4/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch b/projects/RPi/devices/RPi4/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch new file mode 100644 index 0000000000..317adbdbf9 --- /dev/null +++ b/projects/RPi/devices/RPi4/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch @@ -0,0 +1,4102 @@ +diff --git a/configure b/configure +index 2c9359273c..36258ed184 100755 +--- a/configure ++++ b/configure +@@ -1788,6 +1788,8 @@ HWACCEL_LIBRARY_LIST=" + omx + opencl + v4l2_request ++ rpi4_8 ++ rpi4_10 + " + + DOCUMENT_LIST=" +@@ -1849,6 +1851,7 @@ SUBSYSTEM_LIST=" + pixelutils + network + rdft ++ rpi + " + + # COMPONENT_LIST needs to come last to ensure correct dependency checking +@@ -2318,6 +2321,7 @@ CONFIG_EXTRA=" + rangecoder + riffdec + riffenc ++ rpi + rtpdec + rtpenc_chain + rv34dsp +diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c +index c0214c42d8..3f43b58cbb 100644 +--- a/fftools/ffmpeg.c ++++ b/fftools/ffmpeg.c +@@ -23,6 +23,11 @@ + * multimedia converter based on the FFmpeg libraries + */ + ++#ifdef RPI ++//#define RPI_DISPLAY ++#define RPI_DISPLAY_ALL 0 ++#endif ++ + #include "config.h" + #include + #include +@@ -70,6 +75,24 @@ + # include "libavfilter/buffersrc.h" + # include "libavfilter/buffersink.h" + ++#ifdef RPI_DISPLAY ++#pragma GCC diagnostic push ++// Many many redundant decls in the header files ++#pragma GCC diagnostic ignored "-Wredundant-decls" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#pragma GCC diagnostic pop ++#include "libavcodec/rpi_qpu.h" ++#include "libavcodec/rpi_zc.h" ++#endif ++ + #if HAVE_SYS_RESOURCE_H + #include + #include +@@ -162,6 +185,247 @@ static int restore_tty; + static void free_input_threads(void); + #endif + ++#ifdef RPI_DISPLAY ++ ++#define NUM_BUFFERS 4 ++ ++ ++typedef struct rpi_display_env_s ++{ ++ MMAL_COMPONENT_T* display; ++ MMAL_COMPONENT_T* isp; ++ MMAL_PORT_T * port_in; // Input port of either isp or display depending on pipe setup ++ MMAL_CONNECTION_T * conn; ++ ++ MMAL_POOL_T *rpi_pool; ++ volatile int rpi_display_count; ++ enum AVPixelFormat avfmt; ++} rpi_display_env_t; ++ ++static rpi_display_env_t * rpi_display_env = NULL; ++ ++ ++static MMAL_POOL_T* display_alloc_pool(MMAL_PORT_T* port) ++{ ++ MMAL_POOL_T* pool; ++ mmal_port_parameter_set_boolean(port, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); // Does this mark that the buffer contains a vc_handle? Would have expected a vc_image? ++ pool = mmal_port_pool_create(port, NUM_BUFFERS, 0); ++ assert(pool); ++ ++ return pool; ++} ++ ++static void display_cb_input(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { ++ rpi_display_env_t *const de = (rpi_display_env_t *)port->userdata; ++ av_rpi_zc_unref(buffer->user_data); ++ atomic_fetch_add(&de->rpi_display_count, -1); ++ mmal_buffer_header_release(buffer); ++} ++ ++static void display_cb_control(MMAL_PORT_T *port,MMAL_BUFFER_HEADER_T *buffer) { ++ mmal_buffer_header_release(buffer); ++} ++ ++#define DISPLAY_PORT_DEPTH 4 ++ ++static rpi_display_env_t * ++display_init(const enum AVPixelFormat req_fmt, size_t x, size_t y, size_t w, size_t h) ++{ ++ MMAL_STATUS_T err; ++ MMAL_DISPLAYREGION_T region = ++ { ++ .hdr = {MMAL_PARAMETER_DISPLAYREGION, sizeof(region)}, ++ .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_FULLSCREEN | MMAL_DISPLAY_SET_DEST_RECT, ++ .layer = 2, ++ .fullscreen = 0, ++ .dest_rect = {x, y, w, h} ++ }; ++#if RPI_ZC_SAND_8_IN_10_BUF ++ const enum AVPixelFormat fmt = (req_fmt == AV_PIX_FMT_YUV420P10 || av_rpi_is_sand_format(req_fmt)) ? AV_PIX_FMT_SAND128 : req_fmt; ++#else ++ const enum AVPixelFormat fmt = (req_fmt == AV_PIX_FMT_YUV420P10) ? AV_PIX_FMT_SAND128 : req_fmt; ++#endif ++ const AVRpiZcFrameGeometry geo = av_rpi_zc_frame_geometry(fmt, w, h); ++ rpi_display_env_t * de; ++ int isp_req = (fmt == AV_PIX_FMT_SAND64_10); ++ ++ bcm_host_init(); // Needs to be done by someone... ++ ++ if ((de = av_mallocz(sizeof(*de))) == NULL) { ++ return NULL; ++ } ++ ++ mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &de->display); ++ av_assert0(de->display); ++ de->port_in = de->display->input[0]; ++ ++ if (isp_req) ++ { ++ mmal_component_create("vc.ril.isp", &de->isp); ++ de->port_in = de->isp->input[0]; ++ } ++ ++ mmal_port_parameter_set(de->display->input[0], ®ion.hdr); ++ ++ { ++ MMAL_PORT_T * const port = de->port_in; ++ MMAL_ES_FORMAT_T* const format = port->format; ++ port->userdata = (struct MMAL_PORT_USERDATA_T *)de; ++ port->buffer_num = DISPLAY_PORT_DEPTH; ++ format->encoding = ++ fmt == AV_PIX_FMT_SAND128 ? MMAL_ENCODING_YUVUV128 : ++ fmt == AV_PIX_FMT_RPI4_8 ? MMAL_ENCODING_YUVUV128 : ++ fmt == AV_PIX_FMT_RPI4_10 ? MMAL_ENCODING_YUV10_COL : ++ fmt == AV_PIX_FMT_SAND64_10 ? MMAL_ENCODING_YUVUV64_16 : ++ MMAL_ENCODING_I420; ++ format->es->video.width = geo.stride_y; ++ format->es->video.height = (fmt == AV_PIX_FMT_SAND128 || ++ fmt == AV_PIX_FMT_RPI4_8 || ++ fmt == AV_PIX_FMT_RPI4_10 || ++ fmt == AV_PIX_FMT_SAND64_10) ? ++ (h + 15) & ~15 : geo.height_y; // Magic ++ format->es->video.crop.x = 0; ++ format->es->video.crop.y = 0; ++ format->es->video.crop.width = w; ++ format->es->video.crop.height = h; ++ mmal_port_format_commit(port); ++ } ++ ++ de->rpi_pool = display_alloc_pool(de->port_in); ++ mmal_port_enable(de->port_in,display_cb_input); ++ ++ if (isp_req) { ++ MMAL_PORT_T * const port_out = de->isp->output[0]; ++ mmal_log_dump_port(de->port_in); ++ mmal_format_copy(port_out->format, de->port_in->format); ++ if (fmt == AV_PIX_FMT_SAND64_10) { ++ if ((err = mmal_port_parameter_set_int32(de->port_in, MMAL_PARAMETER_CCM_SHIFT, 5)) != MMAL_SUCCESS || ++ (err = mmal_port_parameter_set_int32(port_out, MMAL_PARAMETER_OUTPUT_SHIFT, 1)) != MMAL_SUCCESS) ++ { ++ av_log(NULL, AV_LOG_WARNING, "Failed to set ISP output port shift\n"); ++ } ++ else ++ av_log(NULL, AV_LOG_WARNING, "Set ISP output port shift OK\n"); ++ ++ } ++ port_out->format->encoding = MMAL_ENCODING_I420; ++ mmal_log_dump_port(port_out); ++ if ((err = mmal_port_format_commit(port_out)) != MMAL_SUCCESS) ++ { ++ av_log(NULL, AV_LOG_ERROR, "Failed to set ISP output port format\n"); ++ goto fail; ++ } ++ if ((err = mmal_connection_create(&de->conn, port_out, de->display->input[0], MMAL_CONNECTION_FLAG_TUNNELLING)) != MMAL_SUCCESS) { ++ av_log(NULL, AV_LOG_ERROR, "Failed to create connection\n"); ++ goto fail; ++ } ++ if ((err = mmal_connection_enable(de->conn)) != MMAL_SUCCESS) { ++ av_log(NULL, AV_LOG_ERROR, "Failed to enable connection\n"); ++ goto fail; ++ } ++ mmal_port_enable(de->isp->control,display_cb_control); ++ mmal_component_enable(de->isp); ++ } ++ ++ mmal_component_enable(de->display); ++ mmal_port_enable(de->display->control,display_cb_control); ++ de->avfmt = fmt; ++ ++ printf("Allocated display %dx%d in %dx%d, fmt=%d\n", w, h, geo.stride_y, geo.height_y, fmt); ++ ++ return de; ++ ++fail: ++ // **** Free stuff ++ return NULL; ++} ++ ++static void display_frame(struct AVCodecContext * const s, rpi_display_env_t * const de, const AVFrame* const fr) ++{ ++ MMAL_BUFFER_HEADER_T* buf; ++ ++ if (de == NULL) ++ return; ++ ++ if (atomic_load(&de->rpi_display_count) >= DISPLAY_PORT_DEPTH - 1) { ++ av_log(s, AV_LOG_VERBOSE, "Frame dropped\n"); ++ return; ++ } ++ ++ buf = mmal_queue_get(de->rpi_pool->queue); ++ if (!buf) { ++ // Running too fast so drop the frame ++ printf("Q alloc failure\n"); ++ return; ++ } ++ assert(buf); ++ buf->cmd = 0; ++ buf->offset = 0; // Offset to valid data ++ buf->flags = 0; ++ { ++ const AVRpiZcRefPtr fr_buf = av_rpi_zc_ref(s, fr, de->avfmt, 1); ++ if (fr_buf == NULL) { ++ mmal_buffer_header_release(buf); ++ return; ++ } ++ ++ buf->user_data = fr_buf; ++ buf->data = (uint8_t *)av_rpi_zc_vc_handle(fr_buf); // Cast our handle to a pointer for mmal ++ buf->offset = av_rpi_zc_offset(fr_buf); ++ buf->length = av_rpi_zc_length(fr_buf); ++ buf->alloc_size = av_rpi_zc_numbytes(fr_buf); ++ atomic_fetch_add(&de->rpi_display_count, 1); ++ } ++#if RPI_DISPLAY_ALL ++ while (atomic_load(&de->rpi_display_count) >= DISPLAY_PORT_DEPTH - 1) { ++ usleep(5000); ++ } ++#endif ++ ++ if (mmal_port_send_buffer(de->port_in, buf) != MMAL_SUCCESS) ++ { ++ av_log(s, AV_LOG_ERROR, "mmal_port_send_buffer failed: depth=%d\n", de->rpi_display_count); ++ display_cb_input(de->port_in, buf); ++ } ++} ++ ++static void display_exit(rpi_display_env_t ** const pde) ++{ ++ rpi_display_env_t * const de = *pde; ++ *pde = NULL; ++ ++ if (de != NULL) { ++// sleep(120); ++ ++ if (de->port_in != NULL) { ++ mmal_port_disable(de->port_in); ++ } ++ ++ // The above disable should kick out all buffers - check that ++ if (atomic_load(&de->rpi_display_count) != 0) { ++ av_log(NULL, AV_LOG_WARNING, "Exiting with display count non-zero:%d\n", atomic_load(&de->rpi_display_count)); ++ } ++ ++ if (de->conn != NULL) { ++ mmal_connection_destroy(de->conn); ++ } ++ if (de->isp != NULL) { ++ mmal_component_destroy(de->isp); ++ } ++ if (de->display != NULL) { ++ mmal_component_destroy(de->display); ++ } ++ if (de->rpi_pool != NULL) { ++ mmal_port_pool_destroy(de->display->input[0], de->rpi_pool); ++ } ++ ++ av_free(de); ++ } ++} ++ ++#endif ++ ++ + /* sub2video hack: + Convert subtitles to video with alpha to insert them in filter graphs. + This is a temporary solution until libavfilter gets real subtitles support. +@@ -583,6 +847,11 @@ static void ffmpeg_cleanup(int ret) + avformat_close_input(&input_files[i]->ctx); + av_freep(&input_files[i]); + } ++ ++#ifdef RPI_DISPLAY ++ display_exit(&rpi_display_env); ++#endif ++ + for (i = 0; i < nb_input_streams; i++) { + InputStream *ist = input_streams[i]; + +@@ -594,7 +863,9 @@ static void ffmpeg_cleanup(int ret) + av_freep(&ist->filters); + av_freep(&ist->hwaccel_device); + av_freep(&ist->dts_buffer); +- ++#ifdef RPI_DISPLAY ++ av_rpi_zc_uninit(ist->dec_ctx); ++#endif + avcodec_free_context(&ist->dec_ctx); + + av_freep(&input_streams[i]); +@@ -625,6 +896,7 @@ static void ffmpeg_cleanup(int ret) + } + term_exit(); + ffmpeg_exited = 1; ++ + } + + void remove_avoptions(AVDictionary **a, AVDictionary *b) +@@ -1060,6 +1332,15 @@ static void do_video_out(OutputFile *of, + if (ost->source_index >= 0) + ist = input_streams[ost->source_index]; + ++#ifdef RPI_DISPLAY ++ if (next_picture && ist != NULL) ++ { ++ if (rpi_display_env == NULL) ++ rpi_display_env = display_init(next_picture->format, 0, 0, next_picture->width, next_picture->height); ++ display_frame(ist->dec_ctx, rpi_display_env, next_picture); ++ } ++#endif ++ + frame_rate = av_buffersink_get_frame_rate(filter); + if (frame_rate.num > 0 && frame_rate.den > 0) + duration = 1/(av_q2d(frame_rate) * av_q2d(enc->time_base)); +@@ -1275,7 +1556,7 @@ static void do_video_out(OutputFile *of, + + ost->frames_encoded++; + +- ret = avcodec_send_frame(enc, in_picture); ++ ret = 0;//avcodec_send_frame(enc, in_picture); + if (ret < 0) + goto error; + +@@ -2891,6 +3172,12 @@ static int init_input_stream(int ist_index, char *error, int error_len) + ist->dec_ctx->opaque = ist; + ist->dec_ctx->get_format = get_format; + ist->dec_ctx->get_buffer2 = get_buffer; ++ ++#ifdef RPI_DISPLAY ++ // Overrides the above get_buffer2 ++ av_rpi_zc_init(ist->dec_ctx); ++#endif ++ + ist->dec_ctx->thread_safe_callbacks = 1; + + av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); +diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h +index d44b7a5c72..0c5fa38f1d 100644 +--- a/fftools/ffmpeg.h ++++ b/fftools/ffmpeg.h +@@ -62,6 +62,7 @@ enum HWAccelID { + HWACCEL_VIDEOTOOLBOX, + HWACCEL_QSV, + HWACCEL_CUVID, ++ HWACCEL_RPI, + }; + + typedef struct HWAccel { +@@ -654,6 +655,7 @@ int ffmpeg_parse_options(int argc, char **argv); + int videotoolbox_init(AVCodecContext *s); + int qsv_init(AVCodecContext *s); + int cuvid_init(AVCodecContext *s); ++int rpi_init(AVCodecContext *s); + + HWDevice *hw_device_get_by_name(const char *name); + int hw_device_init_from_string(const char *arg, HWDevice **dev); +diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c +index d7a7eb0662..4ee87e742b 100644 +--- a/fftools/ffmpeg_opt.c ++++ b/fftools/ffmpeg_opt.c +@@ -74,6 +74,10 @@ const HWAccel hwaccels[] = { + #endif + #if CONFIG_CUVID + { "cuvid", cuvid_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA }, ++#endif ++#if CONFIG_RPI ++ { "rpi", rpi_init, HWACCEL_RPI, AV_PIX_FMT_RPI4_8 }, ++ { "rpi", rpi_init, HWACCEL_RPI, AV_PIX_FMT_RPI4_10 }, + #endif + { 0 }, + }; +diff --git a/libavcodec/Makefile b/libavcodec/Makefile +index 8b3eab6fb6..84f7e1a1e4 100644 +--- a/libavcodec/Makefile ++++ b/libavcodec/Makefile +@@ -6,6 +6,10 @@ HEADERS = ac3_parser.h \ + avcodec.h \ + avdct.h \ + avfft.h \ ++ rpi_qpu.h \ ++ rpi_mailbox.h \ ++ rpi_zc.h \ ++ rpi_ctrl_ffmpeg.h \ + d3d11va.h \ + dirac.h \ + dv_profile.h \ +@@ -48,6 +52,10 @@ OBJS = ac3_parser.o \ + qsv_api.o \ + raw.o \ + utils.o \ ++ rpi_qpu.o \ ++ rpi_mailbox.o \ ++ rpi_zc.o \ ++ rpi_ctrl_ffmpeg.o \ + vorbis_parser.o \ + xiph.o \ + +@@ -361,6 +369,7 @@ OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o + OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \ + hevc_cabac.o hevc_refs.o hevcpred.o \ + hevcdsp.o hevc_filter.o hevc_data.o ++OBJS-$(CONFIG_RPI) += rpi_hevc.o + OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o + OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o + OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o +diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h +index 4c4581c895..f519b1d8c4 100644 +--- a/libavcodec/avcodec.h ++++ b/libavcodec/avcodec.h +@@ -3212,7 +3212,13 @@ typedef struct AVCodecContext { + #endif + + /** +- * Audio only. The amount of padding (in samples) appended by the encoder to ++ * Opaque pointer for use by replacement get_buffer2 code ++ * ++ * @author jc (08/02/2016) ++ */ ++ void * get_buffer_context; ++ ++ /* Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. +diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c +index df33433150..a692e685c4 100644 +--- a/libavcodec/hevcdec.c ++++ b/libavcodec/hevcdec.c +@@ -365,12 +365,17 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) + CONFIG_HEVC_V4L2REQUEST_HWACCEL + \ + CONFIG_HEVC_VAAPI_HWACCEL + \ + CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + \ ++ CONFIG_HEVC_RPI4_8_HWACCEL + \ ++ CONFIG_HEVC_RPI4_10_HWACCEL + \ + CONFIG_HEVC_VDPAU_HWACCEL) + enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; + + switch (sps->pix_fmt) { + case AV_PIX_FMT_YUV420P: + case AV_PIX_FMT_YUVJ420P: ++#if CONFIG_HEVC_RPI4_8_HWACCEL ++ *fmt++ = AV_PIX_FMT_RPI4_8; ++#endif + #if CONFIG_HEVC_DXVA2_HWACCEL + *fmt++ = AV_PIX_FMT_DXVA2_VLD; + #endif +@@ -395,6 +400,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) + #endif + break; + case AV_PIX_FMT_YUV420P10: ++#if CONFIG_HEVC_RPI4_10_HWACCEL ++ *fmt++ = AV_PIX_FMT_RPI4_10; ++#endif + #if CONFIG_HEVC_DXVA2_HWACCEL + *fmt++ = AV_PIX_FMT_DXVA2_VLD; + #endif +@@ -3564,6 +3572,12 @@ AVCodec ff_hevc_decoder = { + #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + HWACCEL_VIDEOTOOLBOX(hevc), + #endif ++#if CONFIG_HEVC_RPI4_8_HWACCEL ++ HWACCEL_RPI4_8(hevc), ++#endif ++#if CONFIG_HEVC_RPI4_10_HWACCEL ++ HWACCEL_RPI4_10(hevc), ++#endif + #if CONFIG_HEVC_V4L2REQUEST_HWACCEL + HWACCEL_V4L2REQUEST(hevc), + #endif +diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h +index 2eefc91e7e..0e482f2265 100644 +--- a/libavcodec/hwaccel.h ++++ b/libavcodec/hwaccel.h +@@ -82,5 +82,9 @@ typedef struct AVCodecHWConfigInternal { + HW_CONFIG_HWACCEL(0, 0, 1, XVMC, NONE, ff_ ## codec ## _xvmc_hwaccel) + #define HWACCEL_V4L2REQUEST(codec) \ + HW_CONFIG_HWACCEL(1, 0, 0, DRM_PRIME, DRM, ff_ ## codec ## _v4l2request_hwaccel) ++#define HWACCEL_RPI4_8(codec) \ ++ HW_CONFIG_HWACCEL(0, 0, 1, RPI4_8, NONE, ff_ ## codec ## _rpi4_8_hwaccel) ++#define HWACCEL_RPI4_10(codec) \ ++ HW_CONFIG_HWACCEL(0, 0, 1, RPI4_10, NONE, ff_ ## codec ## _rpi4_10_hwaccel) + + #endif /* AVCODEC_HWACCEL_H */ +diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h +index d183675abe..31a4a94e28 100644 +--- a/libavcodec/hwaccels.h ++++ b/libavcodec/hwaccels.h +@@ -77,5 +77,7 @@ extern const AVHWAccel ff_wmv3_dxva2_hwaccel; + extern const AVHWAccel ff_wmv3_nvdec_hwaccel; + extern const AVHWAccel ff_wmv3_vaapi_hwaccel; + extern const AVHWAccel ff_wmv3_vdpau_hwaccel; ++extern const AVHWAccel ff_hevc_rpi4_8_hwaccel; ++extern const AVHWAccel ff_hevc_rpi4_10_hwaccel; + + #endif /* AVCODEC_HWACCELS_H */ +diff --git a/libavcodec/rpi_ctrl_ffmpeg.c b/libavcodec/rpi_ctrl_ffmpeg.c +new file mode 100644 +index 0000000000..6d93adba03 +--- /dev/null ++++ b/libavcodec/rpi_ctrl_ffmpeg.c +@@ -0,0 +1,427 @@ ++#include ++#include ++#include ++#include ++ ++// How to access GPIO registers from C-code on the Raspberry-Pi ++// Example program ++// 15-January-2012 ++// Dom and Gert ++ ++// Access from ARM Running Linux ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include "rpi_mailbox.h" ++#include "rpi_ctrl_ffmpeg.h" ++ ++#define av_assert0(x) assert(x) ++ ++// argon block doesn't see VC sdram alias bits ++#define MANGLE(x) ((x) &~0xc0000000) ++#ifdef AXI_BUFFERS ++#define AXI_MEM_SIZE (64*1024*1024) ++#else ++#define AXI_MEM_SIZE (64*1024*1024) ++#endif ++ ++#define PAGE_SIZE (4*1024) ++#define BLOCK_SIZE (0x10000) ++#define CACHED 0 ++#define VERBOSE 0 ++ ++static inline void __DMB2(void) {}//{ asm volatile ("dmb" ::: "memory"); } ++ ++ ++// GPU memory alloc fns (internal) ++typedef struct gpu_mem_ptr_s { ++ unsigned char *arm; // Pointer to memory mapped on ARM side ++ int vc_handle; // Videocore handle of relocatable memory ++ int vcsm_handle; // Handle for use by VCSM ++ unsigned int vc; // Address for use in GPU code ++ unsigned int numbytes; // Size of memory block ++} GPU_MEM_PTR_T; ++ ++typedef enum ++{ ++ RPI_CACHE_FLUSH_MODE_INVALIDATE = 1, ++ RPI_CACHE_FLUSH_MODE_WRITEBACK = 2, ++ RPI_CACHE_FLUSH_MODE_WB_INVALIDATE = 3 ++} rpi_cache_flush_mode_t; ++ ++// GPU_MEM_PTR_T alloc fns ++static int gpu_malloc_cached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { ++ p->numbytes = (numbytes + 255) & ~255; // Round up ++ p->vcsm_handle = vcsm_malloc_cache(p->numbytes, VCSM_CACHE_TYPE_HOST | 0x80, (char *)"Video Frame" ); ++ av_assert0(p->vcsm_handle); ++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); ++ av_assert0(p->vc_handle); ++ p->arm = vcsm_lock(p->vcsm_handle); ++ av_assert0(p->arm); ++ p->vc = mbox_mem_lock(mb, p->vc_handle); ++ av_assert0(p->vc); ++ printf("***** %s, %d\n", __func__, numbytes); ++ ++ return 0; ++} ++ ++static int gpu_malloc_uncached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { ++ p->numbytes = numbytes; ++ p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE | 0x80, (char *)"Video Frame" ); ++ av_assert0(p->vcsm_handle); ++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); ++ av_assert0(p->vc_handle); ++ p->arm = vcsm_lock(p->vcsm_handle); ++ av_assert0(p->arm); ++ p->vc = mbox_mem_lock(mb, p->vc_handle); ++ av_assert0(p->vc); ++ printf("***** %s, %d\n", __func__, numbytes); ++ return 0; ++} ++ ++static void gpu_free_internal(const int mb, GPU_MEM_PTR_T * const p) { ++ mbox_mem_unlock(mb, p->vc_handle); ++ vcsm_unlock_ptr(p->arm); ++ vcsm_free(p->vcsm_handle); ++ memset(p, 0, sizeof(*p)); // Ensure we crash hard if we try and use this again ++ printf("***** %s\n", __func__); ++} ++ ++static void gpu_clean_invalidate(GPU_MEM_PTR_T * const p, int mode) { ++ struct vcsm_user_clean_invalid_s iocache = {}; ++ iocache.s[0].handle = p->vcsm_handle; ++ iocache.s[0].cmd = mode; ++ iocache.s[0].addr = (int) p->arm; ++ iocache.s[0].size = p->numbytes; ++ vcsm_clean_invalid( &iocache ); ++ printf("***** %s mode:%d\n", __func__, mode); ++} ++ ++// ++// Set up a memory regions to access periperhals ++// ++static void *setup_io(const char *dev, unsigned long base) ++{ ++ void *gpio_map; ++ int mem_fd; ++ ++ /* open /dev/mem */ ++ if ((mem_fd = open(dev, O_RDWR|O_SYNC) ) < 0) { ++ printf("can't open %s\n", dev); ++ exit (-1); ++ } ++ // Now map it ++ gpio_map = (unsigned char *)mmap( ++ NULL, ++ BLOCK_SIZE, ++ PROT_READ|PROT_WRITE, ++ MAP_SHARED, ++ mem_fd, ++ base ++ ); ++ printf("%s: %08lx -> %p (fd:%d)\n", __FUNCTION__, base, gpio_map, mem_fd); ++ ++ if (gpio_map == MAP_FAILED) { ++ printf("mmap error %p\n", gpio_map); ++ //exit (-1); ++ } ++ ++ return gpio_map; ++} // setup_io ++ ++static void release_io(void *gpio_map) ++{ ++ int s = munmap(gpio_map, BLOCK_SIZE); ++ assert(s == 0); ++} ++ ++struct RPI_DEBUG { ++ FILE *fp_reg; ++ FILE *fp_bin; ++ int mbox; ++ GPU_MEM_PTR_T axi; ++ void *read_buf; ++ int32_t read_buf_size, read_buf_used; ++ volatile unsigned int *apb; ++ volatile unsigned int *interrupt; ++ //volatile unsigned int *sdram; ++}; ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++void rpi_apb_write_addr(void *id, uint16_t addr, uint32_t data) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "P %x %08x\n", addr, data); ++ __DMB2(); ++ rpi->apb[addr>>2] = data + (MANGLE(rpi->axi.vc)>>6); ++} ++ ++uint64_t rpi_axi_get_addr(void *id) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ return (uint64_t)MANGLE(rpi->axi.vc); ++} ++ ++void rpi_apb_write(void *id, uint16_t addr, uint32_t data) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "W %x %08x\n", addr, data); ++ __DMB2(); ++ rpi->apb[addr>>2] = data; ++} ++ ++uint32_t rpi_apb_read(void *id, uint16_t addr) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ uint32_t v = rpi->apb[addr>>2]; ++ __DMB2(); ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "R %x (=%x)\n", addr, v); ++ return v; ++} ++ ++void rpi_apb_read_drop(void *id, uint16_t addr) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ uint32_t v = rpi->apb[addr>>2]; ++ __DMB2(); ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "R %x (=%x)\n", addr, v); ++} ++ ++void rpi_axi_write(void *id, uint64_t addr, uint32_t size, void *buf) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "L %08" PRIx64 " %08x\n", addr, size); ++ assert(addr + size <= AXI_MEM_SIZE); ++ __DMB2(); ++ memcpy(rpi->axi.arm + addr, buf, size); ++} ++ ++void rpi_axi_read_alloc(void *id, uint32_t size) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ assert(rpi->read_buf == NULL); ++ rpi->read_buf = malloc(size); ++ rpi->read_buf_size = size; ++ rpi->read_buf_used = 0; ++} ++ ++void rpi_axi_read_tx(void *id, uint64_t addr, uint32_t size) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ assert(rpi->read_buf_used + size <= rpi->read_buf_size); ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "S %08" PRIx64 " %08x\n", addr, size); ++ assert(addr + size <= AXI_MEM_SIZE); ++ __DMB2(); ++ memcpy((char *)rpi->read_buf + rpi->read_buf_used, rpi->axi.arm + addr, size); ++ rpi->read_buf_used += size; ++} ++ ++void rpi_axi_read_rx(void *id, uint32_t size, void *buf) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ assert(size == rpi->read_buf_used); ++ fprintf(rpi->fp_reg, "Z " PRIx64 " %08x\n", size); ++ memcpy(buf, rpi->read_buf, size); ++ free(rpi->read_buf); ++ rpi->read_buf = NULL; ++ rpi->read_buf_size = 0; ++ rpi->read_buf_used = 0; ++} ++ ++static int getthreadnum(unsigned pid) ++{ ++ static unsigned pids[8]; ++ int i; ++ for (i = 0; i < 8; i++) ++ { ++ if (pids[i] == 0) ++ pids[i] = pid; ++ if (pids[i] == pid) ++ return i; ++ } ++ return -1; ++} ++ ++#define _NOP() //do { __asm__ __volatile__ ("nop"); } while (0) ++ ++static void yield(void) ++{ ++ int i; ++ for (i=0; i<0; i++) ++ _NOP(); ++ usleep(1000); ++} ++ ++ ++void rpi_wait_interrupt(void *id, int phase) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ static struct timespec tfirst={0,0}; ++ static __thread struct timespec tstart={0,0}; ++ struct timespec tend={0,0}; ++ unsigned pid = (unsigned)pthread_self(); ++ clock_gettime(CLOCK_MONOTONIC, &tend); ++ if (tstart.tv_sec == 0 && tstart.tv_nsec == 0) ++ tstart = tend; ++ if (tfirst.tv_sec == 0 && tfirst.tv_nsec == 0) ++ { ++ /*printf("%s: Resetting sdram stats\n", __FUNCTION__); ++ rpi->sdram[0x30/4] = 0;*/ ++ tfirst = tend; ++ } ++ if (VERBOSE) ++ printf("%08llu: %s: IN thread:%u phase:%d time:%llu\n", ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tfirst.tv_sec * 1000000000ULL + tfirst.tv_nsec))/1000, ++ __FUNCTION__, getthreadnum(pid), phase, ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tstart.tv_sec * 1000000000ULL + tstart.tv_nsec))/1000); ++ /*enum {IDL=0x30/4, RTC=0x34/4, WTC=0x38/4, RDC=0x3c/4, WDC=0x40/4, RAC=0x44/4, CYC=0x48/4, CMD=0x4c/4, DAT=0x50/4, RDCMD=0x78/4, RDSUB=0x7c/4, WRCMD=0x80/4, WRSUB=0x84/4, MWRCMD=0x88/4, MWRSUB=0x8c/4,}; ++ printf("IDL:%u RTC:%u WTC:%u RDC:%u WDC:%u RAC:%u CYC:%u CMD:%u DAT:%u RDCMD:%u RDSUB:%u WRCMD:%u WRSUB:%u MWRCMD:%u MWRSUB:%u\n", ++ rpi->sdram[IDL], rpi->sdram[RTC], rpi->sdram[WTC], rpi->sdram[RDC], rpi->sdram[WDC], rpi->sdram[RAC], rpi->sdram[CYC], rpi->sdram[CMD], rpi->sdram[DAT], ++ rpi->sdram[RDCMD], rpi->sdram[RDSUB], rpi->sdram[WRCMD], rpi->sdram[WRSUB], rpi->sdram[MWRCMD], rpi->sdram[MWRSUB]); ++ rpi->sdram[0x30/4] = 0;*/ ++ ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "I %d\n", phase); ++ __DMB2(); ++#if 0 ++ assert(phase == 1 || phase == 2); ++ for (;;) { ++ if (phase==1 && rpi->apb[0x74>>2]==rpi->apb[0x70>>2]) break; ++ else if (phase==2 && (rpi->apb[0x8028/*STATUS2*/>>2]&1)==0) break; ++ } ++ fprintf(rpi->fp_reg, "I %d done\n", phase); ++#else ++ #define ARG_IC_ICTRL_ACTIVE1_INT_SET 0x00000001 ++ #define ARG_IC_ICTRL_ACTIVE1_EDGE_SET 0x00000002 ++ #define ARG_IC_ICTRL_ACTIVE1_EN_SET 0x00000004 ++ #define ARG_IC_ICTRL_ACTIVE1_STATUS_SET 0x00000008 ++ #define ARG_IC_ICTRL_ACTIVE2_INT_SET 0x00000010 ++ #define ARG_IC_ICTRL_ACTIVE2_EDGE_SET 0x00000020 ++ #define ARG_IC_ICTRL_ACTIVE2_EN_SET 0x00000040 ++ #define ARG_IC_ICTRL_ACTIVE2_STATUS_SET 0x00000080 ++ //if (rpi->interrupt[0] &~ (ARG_IC_ICTRL_ACTIVE1_INT_SET|ARG_IC_ICTRL_ACTIVE2_INT_SET|ARG_IC_ICTRL_ACTIVE1_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET|ARG_IC_ICTRL_ACTIVE1_STATUS_SET|ARG_IC_ICTRL_ACTIVE2_STATUS_SET)) ++ //fprintf(rpi->fp_reg, "I %d %x in\n", phase, rpi->interrupt[0]); ++ ++ if (phase == 1) { ++ while (!(rpi->interrupt[0] & ARG_IC_ICTRL_ACTIVE1_INT_SET)) ++ yield(); ++ rpi->interrupt[0] = rpi->interrupt[0] &~ ARG_IC_ICTRL_ACTIVE2_INT_SET; //ARG_IC_ICTRL_ACTIVE1_INT_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET; ++ } else if (phase == 2) { ++ while (!(rpi->interrupt[0] & ARG_IC_ICTRL_ACTIVE2_INT_SET)) ++ yield(); ++ rpi->interrupt[0] = rpi->interrupt[0] &~ ARG_IC_ICTRL_ACTIVE1_INT_SET; //ARG_IC_ICTRL_ACTIVE2_INT_SET|ARG_IC_ICTRL_ACTIVE1_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET; ++ } else assert(0); ++#endif ++ //fprintf(rpi->fp_reg, "I %d %x out\n", phase, rpi->interrupt[0]); ++ if (phase == 2) ++ { ++ __DMB2(); ++ if (VERBOSE) ++ fprintf(rpi->fp_reg, "YBASE:%08x CBASE:%08x\n", rpi->apb[0x8018>>2]*64, rpi->apb[0x8020>>2]*64); ++ } ++ clock_gettime(CLOCK_MONOTONIC, &tend); ++ ++ if (VERBOSE) ++ printf("%08llu: %s: OUT thread:%u phase:%d time:%llu\n", ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tfirst.tv_sec * 1000000000ULL + tfirst.tv_nsec))/1000, ++ __FUNCTION__, getthreadnum(pid), phase, ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tstart.tv_sec * 1000000000ULL + tstart.tv_nsec))/1000); ++ /*printf("IDL:%u RTC:%u WTC:%u RDC:%u WDC:%u RAC:%u CYC:%u CMD:%u DAT:%u RDCMD:%u RDSUB:%u WRCMD:%u WRSUB:%u MWRCMD:%u MWRSUB:%u\n", ++ rpi->sdram[IDL], rpi->sdram[RTC], rpi->sdram[WTC], rpi->sdram[RDC], rpi->sdram[WDC], rpi->sdram[RAC], rpi->sdram[CYC], rpi->sdram[CMD], rpi->sdram[DAT], ++ rpi->sdram[RDCMD], rpi->sdram[RDSUB], rpi->sdram[WRCMD], rpi->sdram[WRSUB], rpi->sdram[MWRCMD], rpi->sdram[MWRSUB]);*/ ++ ++ tstart = tend; ++} ++ ++ ++void rpi_apb_dump_regs(void *id, uint16_t addr, int num) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ int i; ++ __DMB2(); ++ if (VERBOSE) ++ for (i=0; ifp_reg, "%08x: ", 0x7eb00000 + addr + 4*i); ++ fprintf(rpi->fp_reg, "%08x", rpi->apb[(addr>>2)+i]); ++ if ((i%4)==3 || i+1 == num) ++ fprintf(rpi->fp_reg, "\n"); ++ else ++ fprintf(rpi->fp_reg, " "); ++ } ++} ++ ++void rpi_axi_dump(void *id, uint64_t addr, uint32_t size) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ int i; ++ __DMB2(); ++ if (VERBOSE) ++ for (i=0; i>2; i++) ++ { ++ if ((i%4)==0) ++ fprintf(rpi->fp_reg, "%08x: ", MANGLE(rpi->axi.vc) + (uint32_t)addr + 4*i); ++ fprintf(rpi->fp_reg, "%08x", ((uint32_t*)rpi->axi.arm)[(addr>>2)+i]); ++ if ((i%4)==3 || i+1 == size>>2) ++ fprintf(rpi->fp_reg, "\n"); ++ else ++ fprintf(rpi->fp_reg, " "); ++ } ++} ++ ++void rpi_axi_flush(void *id, int mode) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ if (CACHED) ++ { ++ gpu_clean_invalidate(&rpi->axi, mode); ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++const char * rpi_ctrl_ffmpeg_init(const char *hwaccel_device, void **id) { ++ struct RPI_DEBUG *rpi = calloc(1, sizeof(struct RPI_DEBUG)); ++ (void) hwaccel_device; ++ printf("%s\n id=%p\n", __FUNCTION__, rpi); ++ ++ if (!rpi) return "out of memory"; ++ ++ bcm_host_init(); ++ vcsm_init(); ++ rpi->apb = setup_io("/dev/argon-hevcmem", 0); ++ rpi->interrupt = setup_io("/dev/argon-intcmem", 0); ++ //rpi->sdram = setup_io(0xfe001000); ++ ++ rpi->fp_bin = stderr; ++ rpi->fp_reg = stderr; ++ ++ rpi->mbox = mbox_open(); ++ if ((CACHED ? gpu_malloc_cached_internal:gpu_malloc_uncached_internal)(rpi->mbox, AXI_MEM_SIZE, &rpi->axi) != 0) ++ return "out of memory"; ++ ++ fprintf(rpi->fp_reg, "A 100000000 apb:%p axi.arm:%p axi.vc:%08x\n", rpi->apb, rpi->axi.arm, MANGLE(rpi->axi.vc)); ++ *id = rpi; ++ return 0; ++} ++ ++void rpi_ctrl_ffmpeg_free(void *id) { ++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; ++ printf("%s id=%p\n", __FUNCTION__, rpi); ++ release_io(rpi->apb); ++ release_io(rpi->interrupt); ++ gpu_free_internal(rpi->mbox, &rpi->axi); ++ printf("%s freed axi mem\n", __FUNCTION__); ++ mbox_close(rpi->mbox); ++ printf("%s closed mbox\n", __FUNCTION__); ++ free(rpi); ++ printf("%s freed rpi\n", __FUNCTION__); ++ vcsm_exit(); ++ bcm_host_deinit(); ++} +diff --git a/libavcodec/rpi_ctrl_ffmpeg.h b/libavcodec/rpi_ctrl_ffmpeg.h +new file mode 100644 +index 0000000000..6a1d95f195 +--- /dev/null ++++ b/libavcodec/rpi_ctrl_ffmpeg.h +@@ -0,0 +1,29 @@ ++// rpi_ctrl_ffmpeg.h ++// ++// This file contains prototypes for the functions used to control the socket ++// interface when using ffmpeg. ++// ++ ++#ifndef __CTRL_FFMPEG_H__ ++#define __CTRL_FFMPEG_H__ ++ ++#include ++ ++const char *rpi_ctrl_ffmpeg_init (const char *hwaccel_device, void **id); ++void rpi_apb_write_addr (void *id, uint16_t addr, uint32_t data); ++void rpi_apb_write (void *id, uint16_t addr, uint32_t data); ++uint32_t rpi_apb_read (void *id, uint16_t addr); ++void rpi_apb_read_drop (void *id, uint16_t addr); ++void rpi_axi_write (void *id, uint64_t addr, uint32_t size, void *buf); ++void rpi_axi_read (void *id, uint64_t addr, uint32_t size, void *buf); ++void rpi_axi_read_alloc (void *id, uint32_t size); ++void rpi_axi_read_tx (void *id, uint64_t addr, uint32_t size); ++void rpi_axi_read_rx (void *id, uint32_t size, void *buf); ++void rpi_wait_interrupt (void *id, int phase); ++void rpi_ctrl_ffmpeg_free (void *id); ++uint64_t rpi_axi_get_addr (void *id); ++void rpi_apb_dump_regs(void *id, uint16_t addr, int num); ++void rpi_axi_dump(void *id, uint64_t addr, uint32_t size); ++void rpi_axi_flush(void *id, int mode); ++ ++#endif // __CTRL_FILES_H__ +diff --git a/libavcodec/rpi_hevc.c b/libavcodec/rpi_hevc.c +new file mode 100644 +index 0000000000..a000077f33 +--- /dev/null ++++ b/libavcodec/rpi_hevc.c +@@ -0,0 +1,1065 @@ ++// FFMPEG HEVC decoder hardware accelerator ++// Andrew Holme, Argon Design Ltd ++// Copyright (c) June 2017 Raspberry Pi Ltd ++ ++#include ++#include ++ ++#include "fftools/ffmpeg.h" ++#include "libavutil/avassert.h" ++#include "libavutil/imgutils.h" ++#include "avcodec.h" ++#include "hwaccel.h" ++ ++#include "rpi_hevc.h" ++#include "rpi_zc.h" ++#include "rpi_qpu.h" ++ ++#include "rpi_ctrl_ffmpeg.h" ++////////////////////////////////////////////////////////////////////////////// ++ ++// Array of constants for scaling factors ++static const uint32_t scaling_factor_offsets[4][6] = { ++ // MID0 MID1 MID2 MID3 MID4 MID5 ++ {0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050}, // SID0 (4x4) ++ {0x0060, 0x00A0, 0x00E0, 0x0120, 0x0160, 0x01A0}, // SID1 (8x8) ++ {0x01E0, 0x02E0, 0x03E0, 0x04E0, 0x05E0, 0x06E0}, // SID2 (16x16) ++ {0x07E0, 0, 0, 0x0BE0, 0, 0}}; // SID3 (32x32) ++ ++// ffmpeg places SID3,MID1 where matrixID 3 normally is ++ ++////////////////////////////////////////////////////////////////////////////// ++// Scaling factors ++ ++static void expand_scaling_list( ++ RPI_T *rpi, ++ const ScalingList *scaling_list, // scaling list structure from ffmpeg ++ uint8_t sizeID, uint8_t matrixID) ++{ ++ uint8_t x, y, i, blkSize = 4<>1)<<3) + (x>>1); break; ++ case 3: i = ((y>>2)<<3) + (x>>2); ++ } ++ rpi->scaling_factors[index] = scaling_list->sl[sizeID][matrixID][i]; ++ } ++ } ++ if (sizeID>1) ++ rpi->scaling_factors[index_offset] = ++ scaling_list->sl_dc[sizeID-2][matrixID]; ++} ++ ++static void populate_scaling_factors(RPI_T *rpi, HEVCContext *s) { ++ const ScalingList *sl = ++ s->ps.pps->scaling_list_data_present_flag ? &s->ps.pps->scaling_list ++ : &s->ps.sps->scaling_list; ++ int sid, mid; ++ for (sid=0; sid<3; sid++) ++ for (mid=0; mid<6; mid++) ++ expand_scaling_list(rpi, sl, sid, mid); ++ ++ // second scaling matrix for 32x32 is at matrixID 3 not 1 in ffmpeg ++ expand_scaling_list(rpi, sl, 3, 0); ++ expand_scaling_list(rpi, sl, 3, 3); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Probabilities ++ ++static void populate_prob_tables(RPI_T *rpi, HEVCContext *s) { ++ struct RPI_PROB *dst = &rpi->probabilities; ++ struct FFM_PROB *src = (struct FFM_PROB *) s->HEVClc->cabac_state; ++ #define PROB_CPSZ(to, from, sz) memcpy(dst->to, src->from, sz) ++ #define PROB_COPY(to, from) memcpy(dst->to, src->from, sizeof(dst->to)) ++ memset(dst, 0, sizeof(*dst)); ++ PROB_COPY(SAO_MERGE_FLAG , sao_merge_flag ); ++ PROB_COPY(SAO_TYPE_IDX , sao_type_idx ); ++ PROB_COPY(SPLIT_FLAG , split_coding_unit_flag ); ++ PROB_COPY(CU_SKIP_FLAG , skip_flag ); ++ PROB_COPY(CU_TRANSQUANT_BYPASS_FLAG, cu_transquant_bypass_flag ); ++ PROB_COPY(PRED_MODE , pred_mode_flag ); ++ PROB_COPY(PART_SIZE , part_mode ); ++ PROB_COPY(INTRA_PRED_MODE , prev_intra_luma_pred_flag ); ++ PROB_COPY(CHROMA_PRED_MODE , intra_chroma_pred_mode ); ++ PROB_COPY(MERGE_FLAG_EXT , merge_flag ); ++ PROB_COPY(MERGE_IDX_EXT , merge_idx ); ++ PROB_COPY(INTER_DIR , inter_pred_idc ); ++ PROB_COPY(REF_PIC , ref_idx_l0 ); ++ PROB_COPY(MVP_IDX , mvp_lx_flag ); ++ PROB_CPSZ(MVD+0 , abs_mvd_greater0_flag+0 , 1); // ABS_MVD_GREATER0_FLAG[1] not used ++ PROB_CPSZ(MVD+1 , abs_mvd_greater1_flag+1 , 1); // ABS_MVD_GREATER1_FLAG[0] not used ++ PROB_COPY(QT_ROOT_CBF , no_residual_data_flag ); ++ PROB_COPY(TRANS_SUBDIV_FLAG , split_transform_flag ); ++ PROB_CPSZ(QT_CBF , cbf_luma , 2); ++ PROB_CPSZ(QT_CBF+2 , cbf_cb_cr , 4); ++ PROB_COPY(DQP , cu_qp_delta ); ++ PROB_COPY(ONE_FLAG , coeff_abs_level_greater1_flag ); ++ PROB_COPY(LASTX , last_significant_coeff_x_prefix); ++ PROB_COPY(LASTY , last_significant_coeff_y_prefix); ++ PROB_COPY(SIG_CG_FLAG , significant_coeff_group_flag ); ++ PROB_COPY(ABS_FLAG , coeff_abs_level_greater2_flag ); ++ PROB_COPY(TRANSFORMSKIP_FLAG , transform_skip_flag ); ++ PROB_CPSZ(SIG_FLAG , significant_coeff_flag , 42); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Read YUV data from socket server ++ ++static int bytes_per_line(const HEVCSPS *sps, int jump, int x) { ++ int width = FFMIN(jump, sps->width - x); ++ return sps->bit_depth>8? (width>48? 128:64) ++ : (width>64? 128:64); ++} ++ ++static void read_rect(RPI_T *rpi, char *buf, int addr64, int height, int bytes_per_line) { ++ rpi->axi_read_alloc(rpi->id, bytes_per_line*height); ++ if (bytes_per_line==128) ++ rpi->axi_read_tx(rpi->id, ((uint64_t)addr64)<<6, 128*height); ++ else { ++ int y; ++ for (y=0; yaxi_read_tx(rpi->id, ((uint64_t)addr64)<<6, 64); ++ } ++ rpi->axi_read_rx(rpi->id, bytes_per_line*height, buf); ++} ++ ++#ifdef AXI_BUFFERS ++////////////////////////////////////////////////////////////////////////////// ++// Copy YUV output data to FFMPEG frame buffer ++ ++static void copy_luma(char *buf, int bpl, int height, int x, uint8_t *data, int linesize) { ++ int y; ++ for (y=0; y> 0)&0x3ff; if(++j==linesize/2) break; ++ dst[j] = (src[i]>>10)&0x3ff; if(++j==linesize/2) break; ++ dst[j] = (src[i]>>20)&0x3ff; if(++j==linesize/2) break; ++ } ++ } ++} ++ ++static void copy_chroma10(char *buf, int bpl, int height, int x, uint8_t *u8, uint8_t *v8, int linesize) { ++ int i, j, y; ++ for (y=0; y> 0)&0x3ff; ++ v16[j] = (src[i]>>10)&0x3ff; if(++j==linesize/2) break; ++ u16[j] = (src[i]>>20)&0x3ff; i++; ++ v16[j] = (src[i]>> 0)&0x3ff; if(++j==linesize/2) break; ++ u16[j] = (src[i]>>10)&0x3ff; ++ v16[j] = (src[i]>>20)&0x3ff; if(++j==linesize/2) break; ++ } ++ } ++} ++#endif ++ ++////////////////////////////////////////////////////////////////////////////// ++// Phase 1 command and bit FIFOs ++ ++static int p1_apb_write(RPI_T *rpi, uint16_t addr, uint32_t data) { ++ if (rpi->cmd_len==rpi->cmd_max) ++ av_assert0(rpi->cmd_fifo = realloc(rpi->cmd_fifo, (rpi->cmd_max*=2)*sizeof(struct RPI_CMD))); ++ rpi->cmd_fifo[rpi->cmd_len].addr = addr; ++ rpi->cmd_fifo[rpi->cmd_len].data = data; ++ return rpi->cmd_len++; ++} ++ ++static void p1_axi_write(RPI_T *rpi, uint32_t len, const void *ptr, int cmd_idx) { ++ if (rpi->bit_len==rpi->bit_max) ++ av_assert0(rpi->bit_fifo = realloc(rpi->bit_fifo, (rpi->bit_max*=2)*sizeof(struct RPI_BIT))); ++ rpi->bit_fifo[rpi->bit_len].cmd = cmd_idx; ++ rpi->bit_fifo[rpi->bit_len].ptr = ptr; ++ rpi->bit_fifo[rpi->bit_len].len = len; ++ rpi->bit_len++; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Write probability and scaling factor memories ++ ++static void WriteProb(RPI_T *rpi) { ++ int i; ++ uint8_t *p = (uint8_t *) &rpi->probabilities; ++ for (i=0; iscaling_factors; ++ for (i=0; i= bd[i]; i++); // bd[] has num+1 elements; bd[0]=0; see hevc_ps.c ++ return i-1; ++} ++ ++static int ctb_to_slice_w_h (unsigned int ctb, int ctb_size, int width, unsigned int *bd, int num) { ++ if (ctb < bd[num-1]) return ctb_size; ++ else if (width % ctb_size) return width % ctb_size; ++ else return ctb_size; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static void alloc_picture_space(RPI_T *rpi, HEVCContext *s, int thread_idx) { ++ const HEVCSPS *sps = s->ps.sps; ++ int CtbSizeY = 1<log2_ctb_size; ++ int x64 = AXI_BASE64; ++ ++ rpi->PicWidthInCtbsY = (sps->width + CtbSizeY - 1) / CtbSizeY; //7-15 ++ rpi->PicHeightInCtbsY = (sps->height + CtbSizeY - 1) / CtbSizeY; //7-17 ++#ifdef AXI_BUFFERS ++ rpi->lumabytes64 = ((sps->height+64) * ((sps->width+95)/96) * 2); ++ rpi->framebytes64 = ((rpi->lumabytes64 * 3)/2); ++ rpi->lumastride64 = ((sps->height+64) * 128) / 64; ++ rpi->chromastride64 = (((sps->height+64) * 128 ) / 2) / 64; ++ ++ x64 += 17 * rpi->framebytes64; ++#endif ++ ++ // collocated reads/writes ++ if (sps->sps_temporal_mvp_enabled_flag) { ++ // 128 bits = 16 bytes per MV, one for every 16*16 ++ int collocatedStride64 = (rpi->PicWidthInCtbsY * (CtbSizeY/16) * 16 + 63)>>6; ++ rpi->mvframebytes64 = rpi->PicHeightInCtbsY * (CtbSizeY/16) * collocatedStride64; ++ rpi->mvstorage64 = x64; ++ x64 += rpi->mvframebytes64 * 17; // Leave space for 17 reference pictures ++ rpi->colstride64 = collocatedStride64; ++ rpi->mvstride64 = collocatedStride64; ++ } ++ ++ rpi->pubase64[0] = x64; ++} ++ ++static int alloc_stream_space(RPI_T *rpi, HEVCContext *s, int thread_idx) { ++ int stride64, x64 = rpi->pubase64[0]; ++ ++ stride64 = 1 + (rpi->max_pu_msgs*2*rpi->PicWidthInCtbsY)/64; ++ rpi->pubase64[thread_idx] = x64 + rpi->PicHeightInCtbsY*stride64 * thread_idx; ++ rpi->pustep64 = stride64; ++ x64 += rpi->PicHeightInCtbsY*stride64 * s->avctx->thread_count; ++ ++ stride64 = rpi->max_coeff64; ++ rpi->coeffbase64[thread_idx] = x64 + rpi->PicHeightInCtbsY*stride64 * thread_idx; ++ rpi->coeffstep64 = stride64; ++ x64 += rpi->PicHeightInCtbsY*stride64 * s->avctx->thread_count; ++ return x64; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Start or restart phase 1 ++ ++static void phase1_begin(RPI_T *rpi, HEVCContext *s, int thread_idx) { ++ rpi->apb_write_addr(rpi->id, RPI_PUWBASE, rpi->pubase64[thread_idx]); ++ rpi->apb_write(rpi->id, RPI_PUWSTRIDE, rpi->pustep64); ++ rpi->apb_write_addr(rpi->id, RPI_COEFFWBASE, rpi->coeffbase64[thread_idx]); ++ rpi->apb_write(rpi->id, RPI_COEFFWSTRIDE, rpi->coeffstep64); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Wait until phase 2 idle ++ ++static void wait_idle(RPI_T *rpi, int last) { ++ for (;;) { ++ int order; ++ pthread_mutex_lock (&rpi->mutex_phase2); ++ order = rpi->phase2_order; ++ pthread_mutex_unlock(&rpi->mutex_phase2); ++ if (order==last) return; ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Handle PU and COEFF stream overflow ++ ++static int check_status(RPI_T *rpi) { ++ int status, c, p; ++ status = rpi->apb_read(rpi->id, RPI_STATUS); ++ p = (status>>4)&1; ++ c = (status>>3)&1; ++ if (p|c) { // overflow? ++ wait_idle(rpi, rpi->phase1_order-1); // drain phase2 before changing memory layout ++ if (p) rpi->max_pu_msgs += rpi->max_pu_msgs/2; ++ if (c) rpi->max_coeff64 += rpi->max_coeff64/2; ++ return 1; ++ } ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Write STATUS register with expected end CTU address of previous slice ++ ++static void end_previous_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { ++ const HEVCPPS *pps = s->ps.pps; ++ int last_x = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] % rpi->PicWidthInCtbsY; ++ int last_y = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] / rpi->PicWidthInCtbsY; ++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); ++} ++ ++static void wpp_pause(RPI_T *rpi, int ctb_row) { ++ p1_apb_write(rpi, RPI_STATUS, (ctb_row<<18) + 0x25); ++ p1_apb_write(rpi, RPI_TRANSFER, PROB_BACKUP); ++ p1_apb_write(rpi, RPI_MODE, ctb_row==rpi->PicHeightInCtbsY-1?0x70000:0x30000); ++ p1_apb_write(rpi, RPI_CONTROL, (ctb_row<<16) + 2); ++} ++ ++static void wpp_end_previous_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { ++ const HEVCPPS *pps = s->ps.pps; ++ int new_x = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; ++ int new_y = s->sh.slice_ctb_addr_rs / rpi->PicWidthInCtbsY; ++ int last_x = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] % rpi->PicWidthInCtbsY; ++ int last_y = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] / rpi->PicWidthInCtbsY; ++ if (rpi->wpp_entry_x<2 && (rpi->wpp_entry_y2) && rpi->PicWidthInCtbsY>2) wpp_pause(rpi, last_y); ++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); ++ if (new_x==2 || rpi->PicWidthInCtbsY==2 && rpi->wpp_entry_yps.sps; ++ const HEVCPPS *pps = s->ps.pps; ++ ++ p1_apb_write(rpi, RPI_SPS0, ++ (sps->log2_min_cb_size << 0) + ++ (sps->log2_ctb_size << 4) + ++ (sps->log2_min_tb_size << 8) + ++ (sps->log2_max_trafo_size << 12) + ++ (sps->bit_depth << 16) + ++ (sps->bit_depth << 20) + ++ (sps->max_transform_hierarchy_depth_intra << 24) + ++ (sps->max_transform_hierarchy_depth_inter << 28)); ++ ++ p1_apb_write(rpi, RPI_SPS1, ++ (sps->pcm.bit_depth << 0) + ++ (sps->pcm.bit_depth_chroma << 4) + ++ (sps->pcm.log2_min_pcm_cb_size << 8) + ++ (sps->pcm.log2_max_pcm_cb_size << 12) + ++ (sps->separate_colour_plane_flag? 0:sps->chroma_format_idc << 16) + ++ (sps->amp_enabled_flag << 18) + ++ (sps->pcm_enabled_flag << 19) + ++ (sps->scaling_list_enable_flag << 20) + ++ (sps->sps_strong_intra_smoothing_enable_flag << 21)); ++ ++ p1_apb_write(rpi, RPI_PPS, ++ (sps->log2_ctb_size - pps->diff_cu_qp_delta_depth << 0) + ++ (pps->cu_qp_delta_enabled_flag << 4) + ++ (pps->transquant_bypass_enable_flag << 5) + ++ (pps->transform_skip_enabled_flag << 6) + ++ (pps->sign_data_hiding_flag << 7) + ++ (((pps->cb_qp_offset + s->sh.slice_cb_qp_offset)&255) << 8) + ++ (((pps->cr_qp_offset + s->sh.slice_cr_qp_offset)&255) << 16) + ++ (pps->constrained_intra_pred_flag << 24)); ++ ++ if (s->ps.sps->scaling_list_enable_flag) WriteScalingFactors(rpi); ++ ++ if (!s->sh.dependent_slice_segment_flag) { ++ int ctb_col = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; ++ int ctb_row = s->sh.slice_ctb_addr_rs / rpi->PicWidthInCtbsY; ++ rpi->reg_slicestart = (ctb_col<<0) + (ctb_row<<16); ++ } ++ ++ p1_apb_write(rpi, RPI_SLICESTART, rpi->reg_slicestart); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static void write_slice(RPI_T *rpi, HEVCContext *s, uint8_t slice_w, uint8_t slice_h) { ++ uint32_t u32 = ++ (s->sh.slice_type << 12) ++ + (s->sh.slice_sample_adaptive_offset_flag[0] << 14) ++ + (s->sh.slice_sample_adaptive_offset_flag[1] << 15) ++ + (slice_w << 17) ++ + (slice_h << 24); ++ ++ if (s->sh.slice_type==HEVC_SLICE_B || s->sh.slice_type==HEVC_SLICE_P) u32 |= ++ (s->sh.max_num_merge_cand << 0) ++ + (s->sh.nb_refs[L0] << 4) ++ + (s->sh.nb_refs[L1] << 8); ++ ++ if (s->sh.slice_type==HEVC_SLICE_B) u32 |= s->sh.mvd_l1_zero_flag<<16; ++ p1_apb_write(rpi, RPI_SLICE, u32); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Wavefront mode ++ ++static void wpp_entry_point(RPI_T *rpi, HEVCContext *s, int do_bte, int resetQPY, int ctb_addr_ts) { ++ const HEVCSPS *sps = s->ps.sps; ++ const HEVCPPS *pps = s->ps.pps; ++ ++ int ctb_size = 1<log2_ctb_size; ++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; ++ ++ int ctb_col = rpi->wpp_entry_x = ctb_addr_rs % rpi->PicWidthInCtbsY; ++ int ctb_row = rpi->wpp_entry_y = ctb_addr_rs / rpi->PicWidthInCtbsY; ++ ++ int endx = rpi->PicWidthInCtbsY-1; ++ int endy = ctb_row; ++ ++ uint8_t slice_w = ctb_to_slice_w_h(ctb_col, ctb_size, sps->width, pps->col_bd, pps->num_tile_columns); ++ uint8_t slice_h = ctb_to_slice_w_h(ctb_row, ctb_size, sps->height, pps->row_bd, pps->num_tile_rows); ++ ++ p1_apb_write(rpi, RPI_TILESTART, 0); ++ p1_apb_write(rpi, RPI_TILEEND, endx + (endy<<16)); ++ ++ if (do_bte) p1_apb_write(rpi, RPI_BEGINTILEEND, endx + (endy<<16)); ++ ++ write_slice(rpi, s, slice_w, ctb_row==rpi->PicHeightInCtbsY-1? slice_h : ctb_size); ++ ++ if (resetQPY) p1_apb_write(rpi, RPI_QP, sps->qp_bd_offset + s->sh.slice_qp); ++ ++ p1_apb_write(rpi, RPI_MODE, ctb_row==rpi->PicHeightInCtbsY-1? 0x60001 : 0x20001); ++ p1_apb_write(rpi, RPI_CONTROL, (ctb_col<<0) + (ctb_row<<16)); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Tiles mode ++ ++static void new_entry_point(RPI_T *rpi, HEVCContext *s, int do_bte, int resetQPY, int ctb_addr_ts) { ++ const HEVCSPS *sps = s->ps.sps; ++ const HEVCPPS *pps = s->ps.pps; ++ ++ int ctb_col = pps->ctb_addr_ts_to_rs[ctb_addr_ts] % rpi->PicWidthInCtbsY; ++ int ctb_row = pps->ctb_addr_ts_to_rs[ctb_addr_ts] / rpi->PicWidthInCtbsY; ++ ++ int tile_x = ctb_to_tile (ctb_col, pps->col_bd, pps->num_tile_columns); ++ int tile_y = ctb_to_tile (ctb_row, pps->row_bd, pps->num_tile_rows); ++ ++ int endx = pps->col_bd[tile_x+1] - 1; ++ int endy = pps->row_bd[tile_y+1] - 1; ++ ++ uint8_t slice_w = ctb_to_slice_w_h(ctb_col, 1<log2_ctb_size, sps->width, pps->col_bd, pps->num_tile_columns); ++ uint8_t slice_h = ctb_to_slice_w_h(ctb_row, 1<log2_ctb_size, sps->height, pps->row_bd, pps->num_tile_rows); ++ ++ p1_apb_write(rpi, RPI_TILESTART, pps->col_bd[tile_x] + (pps->row_bd[tile_y]<<16)); ++ p1_apb_write(rpi, RPI_TILEEND, endx + (endy<<16)); ++ ++ if (do_bte) p1_apb_write(rpi, RPI_BEGINTILEEND, endx + (endy<<16)); ++ ++ write_slice(rpi, s, slice_w, slice_h); ++ ++ if (resetQPY) p1_apb_write(rpi, RPI_QP, sps->qp_bd_offset + s->sh.slice_qp); ++ ++ p1_apb_write(rpi, RPI_MODE, (0xFFFF << 0) ++ + (0x0 << 16) ++ + ((tile_x==pps->num_tile_columns-1) << 17) ++ + ((tile_y==pps->num_tile_rows-1) << 18)); ++ ++ p1_apb_write(rpi, RPI_CONTROL, (ctb_col<<0) + (ctb_row<<16)); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Workaround for 3 December 2016 commit 8dfba25ce89b62c80ba83e2116d549176c376144 ++// https://github.com/libav/libav/commit/8dfba25ce89b62c80ba83e2116d549176c376144 ++// This commit prevents multi-threaded hardware acceleration by locking hwaccel_mutex ++// around codec->decode() calls. Workaround is to unlock and relock before returning. ++ ++static void hwaccel_mutex(AVCodecContext *avctx, int (*action) (pthread_mutex_t *)) { ++ struct FrameThreadContext { ++ void *foo1, *foo2; // must match struct layout in pthread_frame.c ++ pthread_mutex_t foo3, hwaccel_mutex; ++ }; ++ struct PerThreadContext { ++ struct FrameThreadContext *parent; ++ }; ++ struct PerThreadContext *p = avctx->internal->thread_ctx; ++ if (avctx->thread_count>1) action(&p->parent->hwaccel_mutex); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int get_thread_idx(RPI_T *rpi, AVCodecContext *avctx) { ++ int idx; ++ for (idx=0; idxthread_avctx[idx]==avctx) break; ++ av_assert0(idxinternal->hwaccel_priv_data; ++ HEVCContext *s = avctx->priv_data; ++ ++ int thread_idx = get_thread_idx(rpi, 0); // Find first free slot ++ ++ rpi->thread_avctx[thread_idx] = avctx; ++ rpi->thread_order[thread_idx] = rpi->decode_order++; ++ ++ ff_thread_finish_setup(avctx); // Allow next thread to enter rpi_hevc_start_frame ++ hwaccel_mutex(avctx, pthread_mutex_unlock); ++ ++ // Enforcing phase 1 order precludes busy waiting for phase 2 ++ for (;;) { ++ pthread_mutex_lock (&rpi->mutex_phase1); ++ if (rpi->thread_order[thread_idx]==rpi->phase1_order) break; ++ pthread_mutex_unlock(&rpi->mutex_phase1); ++ } ++ rpi->phase1_order++; ++ ++ alloc_picture_space(rpi, s, thread_idx); ++ rpi->bit_len = rpi->cmd_len = 0; ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Slice messages ++ ++static void msg_slice(RPI_T *rpi, uint16_t msg) { ++ rpi->slice_msgs[rpi->num_slice_msgs++] = msg; ++} ++ ++static void program_slicecmds(RPI_T *rpi, int sliceid) { ++ int i; ++ p1_apb_write(rpi, RPI_SLICECMDS, rpi->num_slice_msgs+(sliceid<<8)); ++ for(i=0; inum_slice_msgs; i++) { ++ p1_apb_write(rpi, 0x4000+4*i, rpi->slice_msgs[i] & 0xffff); ++ } ++} ++ ++static void pre_slice_decode(RPI_T *rpi, HEVCContext *s) { ++ const HEVCSPS *sps = s->ps.sps; ++ const HEVCPPS *pps = s->ps.pps; ++ SliceHeader *sh = &s->sh; ++ ++ int weightedPredFlag, i, rIdx; ++ uint16_t cmd_slice; ++ ++ rpi->num_slice_msgs=0; ++ cmd_slice = 0; ++ if (sh->slice_type==HEVC_SLICE_I) cmd_slice = 1; ++ if (sh->slice_type==HEVC_SLICE_P) cmd_slice = 2; ++ if (sh->slice_type==HEVC_SLICE_B) cmd_slice = 3; ++ ++ if (sh->slice_type!=HEVC_SLICE_I) { ++ cmd_slice += sh->nb_refs[L0]<<2; ++ cmd_slice += sh->nb_refs[L1]<<6; ++ } ++ if (sh->slice_type==HEVC_SLICE_P ++ || sh->slice_type==HEVC_SLICE_B) rpi->max_num_merge_cand = sh->max_num_merge_cand; ++ ++ cmd_slice += rpi->max_num_merge_cand<<11; ++ ++ if (sh->slice_temporal_mvp_enabled_flag) { ++ if (sh->slice_type==HEVC_SLICE_B) rpi->collocated_from_l0_flag = sh->collocated_list==L0; ++ else if (sh->slice_type==HEVC_SLICE_P) rpi->collocated_from_l0_flag = 1; ++ } ++ cmd_slice += rpi->collocated_from_l0_flag<<14; ++ ++ if (sh->slice_type==HEVC_SLICE_P || sh->slice_type==HEVC_SLICE_B) { ++ ++ int NoBackwardPredFlag = 1; // Flag to say all reference pictures are from the past ++ for(i=L0; i<=L1; i++) { ++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { ++ HEVCFrame *f = s->ref->refPicList[i].ref[rIdx]; ++ HEVCFrame *c = s->ref; // CurrentPicture ++ if (c->poc < f->poc) NoBackwardPredFlag = 0; ++ } ++ } ++ ++ rpi->collocated_ref_idx = sh->collocated_ref_idx; ++ if (s->ref->refPicList && s->ref->collocated_ref) ++ for (i=0; inb_refs[L1]) rpi->RefPicList[1][i] = s->ref->refPicList[1].ref[i] - s->DPB; ++ if (inb_refs[L0]) rpi->RefPicList[0][i] = s->ref->refPicList[0].ref[i] - s->DPB; ++ } ++ ++ cmd_slice += NoBackwardPredFlag<<10; ++ msg_slice(rpi, cmd_slice); ++ ++ // Write reference picture descriptions ++ weightedPredFlag = sh->slice_type==HEVC_SLICE_P? pps->weighted_pred_flag : pps->weighted_bipred_flag; ++ ++ for(i=L0; i<=L1; i++) ++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { ++ HEVCFrame *f = s->ref->refPicList[i].ref[rIdx]; ++ HEVCFrame *c = s->ref; // CurrentPicture ++ int pic = f - s->DPB; ++ // Make sure pictures are in range 0 to 15 ++ int adjusted_pic = fref->refPicList[i].isLongTerm[rIdx]; ++ msg_slice(rpi, adjusted_pic+(lt<<4)+(weightedPredFlag<<5)+(weightedPredFlag<<6)); ++ msg_slice(rpi, f->poc); ++ if (weightedPredFlag) { ++ msg_slice(rpi, s->sh.luma_log2_weight_denom+(((i?s-> sh.luma_weight_l1: s->sh.luma_weight_l0)[rIdx] &0x1ff)<<3)); ++ msg_slice(rpi, (i?s-> sh.luma_offset_l1: s->sh.luma_offset_l0)[rIdx] & 0xff); ++ msg_slice(rpi, s->sh.chroma_log2_weight_denom+(((i?s->sh.chroma_weight_l1:s->sh.chroma_weight_l0)[rIdx][0]&0x1ff)<<3)); ++ msg_slice(rpi, (i?s->sh.chroma_offset_l1:s->sh.chroma_offset_l0)[rIdx][0]& 0xff); ++ msg_slice(rpi, s->sh.chroma_log2_weight_denom+(((i?s->sh.chroma_weight_l1:s->sh.chroma_weight_l0)[rIdx][1]&0x1ff)<<3)); ++ msg_slice(rpi, (i?s->sh.chroma_offset_l1:s->sh.chroma_offset_l0)[rIdx][1]& 0xff); ++ } ++ } ++ } ++ else ++ msg_slice(rpi, cmd_slice); ++ ++ msg_slice(rpi, ((sh->beta_offset/2)&15) ++ + (((sh->tc_offset/2)&15) << 4) ++ + (sh->disable_deblocking_filter_flag << 8) ++ + (sh->slice_loop_filter_across_slices_enabled_flag << 9) ++ + (pps->loop_filter_across_tiles_enabled_flag << 10)); // CMD_DEBLOCK ++ ++ msg_slice(rpi, ((sh->slice_cr_qp_offset&31)<<5) + (sh->slice_cb_qp_offset&31)); // CMD_QPOFF ++ ++ // collocated reads/writes ++ if (sps->sps_temporal_mvp_enabled_flag) { ++ int thread_idx = get_thread_idx(rpi, s->avctx); ++ int CurrentPicture = s->ref - s->DPB; ++ int colPic = rpi->RefPicList[sh->slice_type==HEVC_SLICE_B && rpi->collocated_from_l0_flag==0][rpi->collocated_ref_idx]; ++ rpi->mvbase64 [thread_idx] = rpi->mvstorage64 + CurrentPicture * rpi->mvframebytes64; ++ if (sh->slice_type==HEVC_SLICE_I) { ++ // Collocated picture not well defined here. Use mvbase or previous value ++ if (sh->first_slice_in_pic_flag) ++ rpi->colbase64[thread_idx] = rpi->mvbase64[thread_idx]; // Ensure we don't read garbage ++ } ++ else ++ rpi->colbase64[thread_idx] = rpi->mvstorage64 + colPic * rpi->mvframebytes64; ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// End frame ++ ++static int rpi_hevc_end_frame(AVCodecContext *avctx) { ++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; ++ HEVCContext *s = avctx->priv_data; ++ const HEVCPPS *pps = s->ps.pps; ++ const HEVCSPS *sps = s->ps.sps; ++ int thread_idx = get_thread_idx(rpi, avctx); ++ int jump = sps->bit_depth>8?96:128; ++ int CurrentPicture = s->ref - s->DPB; ++ AVFrame *f = s->ref->frame; ++ int last_x = pps->col_bd[pps->num_tile_columns]-1; ++ int last_y = pps->row_bd[pps->num_tile_rows]-1; ++ ++ int i, a64, x; ++ char *buf; ++ ++ // End of phase 1 command compilation ++ if (pps->entropy_coding_sync_enabled_flag) { ++ if (rpi->wpp_entry_x<2 && rpi->PicWidthInCtbsY>2) wpp_pause(rpi, last_y); ++ } ++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); ++ ++ // Phase 1 ... ++ for (;;) { ++ // (Re-)allocate PU/COEFF stream space ++ a64 = alloc_stream_space(rpi, s, thread_idx); ++ // Send bitstream data ++ for (i=0; ibit_len; i++) { ++ rpi->axi_write(rpi->id, ((uint64_t)a64)<<6, rpi->bit_fifo[i].len, rpi->bit_fifo[i].ptr); ++ rpi->cmd_fifo[rpi->bit_fifo[i].cmd].data = a64 + (rpi->axi_get_addr(rpi->id)>>6); // Set BFBASE ++ a64 += (rpi->bit_fifo[i].len+63)/64; ++ } ++ // Send phase 1 commands (cache flush on real hardware) ++ rpi->axi_write(rpi->id, ((uint64_t)a64)<<6, rpi->cmd_len * sizeof(struct RPI_CMD), rpi->cmd_fifo); ++ rpi->axi_flush(rpi->id, 3); ++ phase1_begin(rpi, s, thread_idx); ++ // Trigger command FIFO ++ rpi->apb_write(rpi->id, RPI_CFNUM, rpi->cmd_len); ++ rpi->apb_dump_regs(rpi->id, 0x0, 32); ++ rpi->apb_dump_regs(rpi->id, 0x8000, 24); ++ rpi->axi_dump(rpi->id, ((uint64_t)a64)<<6, rpi->cmd_len * sizeof(struct RPI_CMD)); ++ rpi->apb_write_addr(rpi->id, RPI_CFBASE, a64); ++ rpi->wait_interrupt(rpi->id, 1); ++ if (check_status(rpi)==0) break; // No PU/COEFF overflow? ++ } ++ pthread_mutex_unlock(&rpi->mutex_phase1); ++ ++ // Phase 2 ... ++ for (;;) { ++ pthread_mutex_lock (&rpi->mutex_phase2); ++ if (rpi->thread_order[thread_idx]==rpi->phase2_order) break; ++ pthread_mutex_unlock(&rpi->mutex_phase2); ++ } ++ rpi->phase2_order++; ++ ++ rpi->apb_write_addr(rpi->id, RPI_PURBASE, rpi->pubase64[thread_idx]); ++ rpi->apb_write(rpi->id, RPI_PURSTRIDE, rpi->pustep64); ++ rpi->apb_write_addr(rpi->id, RPI_COEFFRBASE, rpi->coeffbase64[thread_idx]); ++ rpi->apb_write(rpi->id, RPI_COEFFRSTRIDE, rpi->coeffstep64); ++ ++#if !defined(AXI_BUFFERS) ++#define MANGLE(x) (((x) &~0xc0000000)>>6) ++{ ++ const AVRpiZcRefPtr fr_buf = f ? av_rpi_zc_ref(avctx, f, f->format, 0) : NULL; ++ uint32_t handle = fr_buf ? av_rpi_zc_vc_handle(fr_buf):0; ++// printf("%s cur:%d fr:%p handle:%d YUV:%x:%x ystride:%d ustride:%d ah:%d\n", __FUNCTION__, CurrentPicture, f, handle, get_vc_address_y(f), get_vc_address_u(f), f->linesize[0], f->linesize[1], f->linesize[3]); ++ rpi->apb_write(rpi->id, RPI_OUTYBASE, MANGLE(get_vc_address_y(f))); ++ rpi->apb_write(rpi->id, RPI_OUTCBASE, MANGLE(get_vc_address_u(f))); ++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, f->linesize[3] * 128 / 64); ++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, f->linesize[3] * 128 / 64); ++ av_rpi_zc_unref(fr_buf); ++} ++#else ++ // Output frame and reference picture locations ++ rpi->apb_write_addr(rpi->id, RPI_OUTYBASE, CurrentPicture * rpi->framebytes64); ++ rpi->apb_write_addr(rpi->id, RPI_OUTCBASE, CurrentPicture * rpi->framebytes64 + rpi->lumabytes64); ++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, rpi->lumastride64); ++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, rpi->chromastride64); ++#endif ++ ++#if !defined(AXI_BUFFERS) ++{ ++ SliceHeader *sh = &s->sh; ++ int rIdx; ++ for(i=0; i<16; i++) { ++ rpi->apb_write(rpi->id, 0x9000+16*i, 0); ++ rpi->apb_write(rpi->id, 0x9004+16*i, 0); ++ rpi->apb_write(rpi->id, 0x9008+16*i, 0); ++ rpi->apb_write(rpi->id, 0x900C+16*i, 0); ++ } ++ ++ for(i=L0; i<=L1; i++) ++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { ++ HEVCFrame *f1 = s->ref->refPicList[i].ref[rIdx]; ++ HEVCFrame *c = s->ref; // CurrentPicture ++ int pic = f1 - s->DPB; ++ // Make sure pictures are in range 0 to 15 ++ int adjusted_pic = f1DPB[pic]; ++ AVFrame *fr = hevc ? hevc->frame : NULL; ++ const AVRpiZcRefPtr fr_buf = fr ? av_rpi_zc_ref(avctx, fr, fr->format, 0) : NULL; ++ uint32_t handle = fr_buf ? av_rpi_zc_vc_handle(fr_buf):0; ++// printf("%s pic:%d (%d,%d,%d) fr:%p handle:%d YUV:%x:%x\n", __FUNCTION__, adjusted_pic, i, rIdx, pic, fr, handle, get_vc_address_y(fr), get_vc_address_u(fr)); ++ rpi->apb_write(rpi->id, 0x9000+16*adjusted_pic, MANGLE(get_vc_address_y(fr))); ++ rpi->apb_write(rpi->id, 0x9008+16*adjusted_pic, MANGLE(get_vc_address_u(fr))); ++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, fr->linesize[3] * 128 / 64); ++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, fr->linesize[3] * 128 / 64); ++ av_rpi_zc_unref(fr_buf); ++ } ++} ++#else ++ for(i=0; i<16; i++) { ++ int pic = i < CurrentPicture ? i : i+1; ++ rpi->apb_write_addr(rpi->id, 0x9000+16*i, pic * rpi->framebytes64); ++ rpi->apb_write(rpi->id, 0x9004+16*i, rpi->lumastride64); ++ rpi->apb_write_addr(rpi->id, 0x9008+16*i, pic * rpi->framebytes64 + rpi->lumabytes64); ++ rpi->apb_write(rpi->id, 0x900C+16*i, rpi->chromastride64); ++ } ++#endif ++ ++ rpi->apb_write(rpi->id, RPI_CONFIG2, ++ (sps->bit_depth << 0) // BitDepthY ++ + (sps->bit_depth << 4) // BitDepthC ++ + ((sps->bit_depth>8) << 8) // BitDepthY ++ + ((sps->bit_depth>8) << 9) // BitDepthC ++ + (sps->log2_ctb_size <<10) ++ + (pps->constrained_intra_pred_flag <<13) ++ + (sps->sps_strong_intra_smoothing_enable_flag<<14) ++ + (sps->sps_temporal_mvp_enabled_flag <<15) ++ + (pps->log2_parallel_merge_level <<16) ++ + (s->sh.slice_temporal_mvp_enabled_flag <<19) ++ + (sps->pcm.loop_filter_disable_flag <<20) ++ + ((pps->cb_qp_offset&31) <<21) ++ + ((pps->cr_qp_offset&31) <<26)); ++ ++ rpi->apb_write(rpi->id, RPI_FRAMESIZE, (sps->height<<16) + sps->width); ++ rpi->apb_write(rpi->id, RPI_CURRPOC, s->poc); ++ ++ // collocated reads/writes ++ if (sps->sps_temporal_mvp_enabled_flag) { ++ rpi->apb_write(rpi->id, RPI_COLSTRIDE, rpi->colstride64); ++ rpi->apb_write(rpi->id, RPI_MVSTRIDE, rpi->mvstride64); ++ rpi->apb_write_addr(rpi->id, RPI_MVBASE, rpi->mvbase64 [thread_idx]); ++ rpi->apb_write_addr(rpi->id, RPI_COLBASE, rpi->colbase64[thread_idx]); ++ } ++ ++ rpi->apb_dump_regs(rpi->id, 0x0, 32); ++ rpi->apb_dump_regs(rpi->id, 0x8000, 24); ++ rpi->apb_write(rpi->id, RPI_NUMROWS, rpi->PicHeightInCtbsY); ++ rpi->apb_read_drop(rpi->id, RPI_NUMROWS); // Read back to confirm write has reached block ++ rpi->wait_interrupt(rpi->id, 2); ++ ++//printf("%s: %dx%d %d\n", __FUNCTION__, f->width, f->height, f->linesize[0]); ++#if defined(AXI_BUFFERS) ++ // Copy YUV output frame ++ av_assert0(buf = malloc(128*sps->height)); ++ a64 = AXI_BASE64 + CurrentPicture * rpi->framebytes64; ++ for(x=0; xwidth; x+=jump) { ++ int bpl = bytes_per_line(sps, jump, x); ++ read_rect(rpi, buf, a64, sps->height, bpl); ++ (sps->bit_depth>8?copy_luma10:copy_luma)(buf, bpl, sps->height, x, f->data[0], f->linesize[0]); ++ a64 += rpi->lumastride64; ++ } ++ a64 = AXI_BASE64 + CurrentPicture * rpi->framebytes64 + rpi->lumabytes64; ++ for(x=0; xwidth; x+=jump) { ++ int bpl = bytes_per_line(sps, jump, x); ++ read_rect(rpi, buf, a64, sps->height/2, bpl); ++ (sps->bit_depth>8?copy_chroma10:copy_chroma)(buf, bpl, sps->height/2, x/2, f->data[1], f->data[2], f->linesize[1]); ++ a64 += rpi->chromastride64; ++ } ++ free(buf); ++#endif ++ rpi->thread_avctx[thread_idx] = 0; ++ pthread_mutex_unlock(&rpi->mutex_phase2); ++ hwaccel_mutex(avctx, pthread_mutex_lock); ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static void WriteBitstream(RPI_T *rpi, HEVCContext *s) { ++ const int rpi_use_emu = 0; // FFmpeg removes emulation prevention bytes ++ const int offset = 0; // Always 64-byte aligned in sim, need not be on real hardware ++ GetBitContext *gb = &s->HEVClc->gb; ++ int len = 1 + gb->size_in_bits/8 - gb->index/8; ++ const void *ptr = &gb->buffer[gb->index/8]; ++ ++ p1_axi_write(rpi, len, ptr, p1_apb_write(rpi, RPI_BFBASE, 0)); // BFBASE set later ++ p1_apb_write(rpi, RPI_BFNUM, len); ++ p1_apb_write(rpi, RPI_BFCONTROL, offset + (1<<7)); // Stop ++ p1_apb_write(rpi, RPI_BFCONTROL, offset + (rpi_use_emu<<6)); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Wavefront mode ++ ++static void wpp_decode_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { ++ const HEVCPPS *pps = s->ps.pps; ++ ++ int i, resetQPY=1; ++ int indep = !s->sh.dependent_slice_segment_flag; ++ int ctb_col = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; ++ ++ if (ctb_addr_ts) wpp_end_previous_slice(rpi, s, ctb_addr_ts); ++ pre_slice_decode(rpi, s); ++ WriteBitstream(rpi, s); ++ if (ctb_addr_ts==0 || indep || rpi->PicWidthInCtbsY==1) WriteProb(rpi); ++ else if (ctb_col==0) p1_apb_write(rpi, RPI_TRANSFER, PROB_RELOAD); ++ else resetQPY=0; ++ program_slicecmds(rpi, s->slice_idx); ++ new_slice_segment(rpi, s); ++ wpp_entry_point(rpi, s, indep, resetQPY, ctb_addr_ts); ++ for (i=0; ish.num_entry_point_offsets; i++) { ++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; ++ int ctb_row = ctb_addr_rs / rpi->PicWidthInCtbsY; ++ int last_x = rpi->PicWidthInCtbsY-1; ++ if (rpi->PicWidthInCtbsY>2) wpp_pause(rpi, ctb_row); ++ p1_apb_write(rpi, RPI_STATUS, (ctb_row<<18) + (last_x<<5) + 2); ++ if (rpi->PicWidthInCtbsY==2) p1_apb_write(rpi, RPI_TRANSFER, PROB_BACKUP); ++ if (rpi->PicWidthInCtbsY==1) WriteProb(rpi); ++ else p1_apb_write(rpi, RPI_TRANSFER, PROB_RELOAD); ++ ctb_addr_ts += pps->column_width[0]; ++ wpp_entry_point(rpi, s, 0, 1, ctb_addr_ts); ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Tiles mode ++ ++static void decode_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { ++ const HEVCPPS *pps = s->ps.pps; ++ int i, resetQPY; ++ ++ if (ctb_addr_ts) end_previous_slice(rpi, s, ctb_addr_ts); ++ pre_slice_decode(rpi, s); ++ WriteBitstream(rpi, s); ++ resetQPY = ctb_addr_ts==0 ++ || pps->tile_id[ctb_addr_ts]!=pps->tile_id[ctb_addr_ts-1] ++ || !s->sh.dependent_slice_segment_flag; ++ if (resetQPY) WriteProb(rpi); ++ program_slicecmds(rpi, s->slice_idx); ++ new_slice_segment(rpi, s); ++ new_entry_point(rpi, s, !s->sh.dependent_slice_segment_flag, resetQPY, ctb_addr_ts); ++ for (i=0; ish.num_entry_point_offsets; i++) { ++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; ++ int ctb_col = ctb_addr_rs % rpi->PicWidthInCtbsY; ++ int ctb_row = ctb_addr_rs / rpi->PicWidthInCtbsY; ++ int tile_x = ctb_to_tile (ctb_col, pps->col_bd, pps->num_tile_columns); ++ int tile_y = ctb_to_tile (ctb_row, pps->row_bd, pps->num_tile_rows); ++ int last_x = pps->col_bd[tile_x+1]-1; ++ int last_y = pps->row_bd[tile_y+1]-1; ++ p1_apb_write(rpi, RPI_STATUS, 2 + (last_x<<5) + (last_y<<18)); ++ WriteProb(rpi); ++ ctb_addr_ts += pps->column_width[tile_x] * pps->row_height[tile_y]; ++ new_entry_point(rpi, s, 0, 1, ctb_addr_ts); ++ } ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int rpi_hevc_decode_slice( ++ AVCodecContext *avctx, ++ const uint8_t *buffer, ++ uint32_t size) { ++ ++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; ++ HEVCContext *s = avctx->priv_data; ++ const HEVCPPS *pps = s->ps.pps; ++ int ctb_addr_ts = pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]; ++ ff_hevc_cabac_init(s, ctb_addr_ts); ++ if (s->ps.sps->scaling_list_enable_flag) populate_scaling_factors(rpi, s); ++ populate_prob_tables(rpi, s); ++ pps->entropy_coding_sync_enabled_flag? wpp_decode_slice(rpi, s, ctb_addr_ts) ++ : decode_slice(rpi, s, ctb_addr_ts); ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++// Bind to socket client ++ ++static int open_socket_client(RPI_T *rpi, const char *so) { ++ *(void **) &rpi->ctrl_ffmpeg_init = rpi_ctrl_ffmpeg_init; ++ *(void **) &rpi->apb_write = rpi_apb_write; ++ *(void **) &rpi->apb_write_addr = rpi_apb_write_addr; ++ *(void **) &rpi->apb_read = rpi_apb_read; ++ *(void **) &rpi->apb_read_drop = rpi_apb_read_drop; ++ *(void **) &rpi->axi_write = rpi_axi_write; ++ *(void **) &rpi->axi_read_alloc = rpi_axi_read_alloc; ++ *(void **) &rpi->axi_read_tx = rpi_axi_read_tx; ++ *(void **) &rpi->axi_read_rx = rpi_axi_read_rx; ++ *(void **) &rpi->axi_get_addr = rpi_axi_get_addr; ++ *(void **) &rpi->apb_dump_regs = rpi_apb_dump_regs; ++ *(void **) &rpi->axi_dump = rpi_axi_dump; ++ *(void **) &rpi->axi_flush = rpi_axi_flush; ++ *(void **) &rpi->wait_interrupt = rpi_wait_interrupt; ++ *(void **) &rpi->ctrl_ffmpeg_free = rpi_ctrl_ffmpeg_free; ++ return 1; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int rpi_hevc_alloc_frame(AVCodecContext *avctx, AVFrame *f) { ++ HEVCContext *s = avctx->priv_data; ++ const HEVCSPS *sps = s->ps.sps; ++ const int ALIGN = 16; ++ ++ f->width = sps->width; ++ f->height = sps->height; ++ f->format = sps->pix_fmt; ++ f->buf[0] = av_buffer_alloc(1); ++ f->buf[1] = av_buffer_alloc(1); ++ f->buf[2] = av_buffer_alloc(1); ++ return av_image_alloc(f->data, f->linesize, f->width, f->height, f->format, ALIGN); ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int rpi_hevc_init(AVCodecContext *avctx) { ++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; ++ const char *err, *so; ++ ++ so = "./rpi_ffmpeg.so"; ++ ++ if (avctx->width>4096 || avctx->height>4096) { ++ av_log(NULL, AV_LOG_FATAL, "Picture size %dx%d exceeds 4096x4096 maximum for HWAccel\n", avctx->width, avctx->height); ++ return AVERROR(ENOTSUP); ++ } ++ if (!open_socket_client(rpi, so)) { ++ av_log(NULL, AV_LOG_FATAL, "%s\n", dlerror()); ++ return AVERROR_EXTERNAL; ++ } ++ err = rpi->ctrl_ffmpeg_init(NULL, &rpi->id); ++ if (err) { ++ av_log(NULL, AV_LOG_FATAL, "Could not connect to RPI server: %s\n", err); ++ return AVERROR_EXTERNAL; ++ } ++ ++#ifdef RPI_DISPLAY ++ #include "rpi_zc.h" ++ // Whilst FFmpegs init fn is only called once the close fn is called as ++ // many times as we have threads (init_thread_copy is called for the ++ // threads). So to match init & term put the init here where it will be ++ // called by both init & copy ++ av_rpi_zc_init(avctx); ++#endif ++ ++ pthread_mutex_init(&rpi->mutex_phase1, NULL); ++ pthread_mutex_init(&rpi->mutex_phase2, NULL); ++ ++ // Initial PU/COEFF stream buffer sizes chosen so jellyfish40.265 requires 1 overflow/restart ++ rpi->max_pu_msgs = 2+340; // 7.2 says at most 1611 messages per CTU ++ rpi->max_coeff64 = 2+1404; ++ ++ av_assert0(rpi->cmd_fifo = malloc((rpi->cmd_max=1024)*sizeof(struct RPI_CMD))); ++ av_assert0(rpi->bit_fifo = malloc((rpi->bit_max=1024)*sizeof(struct RPI_BIT))); ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++static int rpi_hevc_free(AVCodecContext *avctx) { ++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; ++ if (rpi->decode_order) wait_idle(rpi, rpi->decode_order); ++ if (rpi->cmd_fifo) free(rpi->cmd_fifo); ++ if (rpi->bit_fifo) free(rpi->bit_fifo); ++ pthread_mutex_destroy(&rpi->mutex_phase1); ++ pthread_mutex_destroy(&rpi->mutex_phase2); ++ if (rpi->id && rpi->ctrl_ffmpeg_free) rpi->ctrl_ffmpeg_free(rpi->id); ++ return 0; ++} ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++const AVHWAccel ff_hevc_rpi4_8_hwaccel = { ++ .name = "hevc_rpi4_8", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = AV_CODEC_ID_HEVC, ++ .pix_fmt = AV_PIX_FMT_RPI4_8, ++ //.alloc_frame = rpi_hevc_alloc_frame, ++ .start_frame = rpi_hevc_start_frame, ++ .end_frame = rpi_hevc_end_frame, ++ .decode_slice = rpi_hevc_decode_slice, ++ .init = rpi_hevc_init, ++ .uninit = rpi_hevc_free, ++ .priv_data_size = sizeof(RPI_T), ++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE, ++}; ++ ++const AVHWAccel ff_hevc_rpi4_10_hwaccel = { ++ .name = "hevc_rpi4_10", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = AV_CODEC_ID_HEVC, ++ .pix_fmt = AV_PIX_FMT_RPI4_10, ++ //.alloc_frame = rpi_hevc_alloc_frame, ++ .start_frame = rpi_hevc_start_frame, ++ .end_frame = rpi_hevc_end_frame, ++ .decode_slice = rpi_hevc_decode_slice, ++ .init = rpi_hevc_init, ++ .uninit = rpi_hevc_free, ++ .priv_data_size = sizeof(RPI_T), ++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE, ++}; ++ ++ ++int rpi_init(AVCodecContext *avctx) { ++ return 0; ++} +diff --git a/libavcodec/rpi_hevc.h b/libavcodec/rpi_hevc.h +new file mode 100644 +index 0000000000..f54657a957 +--- /dev/null ++++ b/libavcodec/rpi_hevc.h +@@ -0,0 +1,219 @@ ++// FFMPEG HEVC decoder hardware accelerator ++// Andrew Holme, Argon Design Ltd ++// Copyright (c) June 2017 Raspberry Pi Ltd ++ ++#include ++#include ++ ++#include "hevc.h" ++#include "hevcdec.h" ++ ++#define MAX_THREADS 50 ++#define NUM_SCALING_FACTORS 4064 ++ ++#define AXI_BASE64 0 ++ ++#define PROB_BACKUP ((20<<12) + (20<<6) + (0<<0)) ++#define PROB_RELOAD ((20<<12) + (20<<0) + (0<<6)) ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++#define RPI_SPS0 0 ++#define RPI_SPS1 4 ++#define RPI_PPS 8 ++#define RPI_SLICE 12 ++#define RPI_TILESTART 16 ++#define RPI_TILEEND 20 ++#define RPI_SLICESTART 24 ++#define RPI_MODE 28 ++#define RPI_LEFT0 32 ++#define RPI_LEFT1 36 ++#define RPI_LEFT2 40 ++#define RPI_LEFT3 44 ++#define RPI_QP 48 ++#define RPI_CONTROL 52 ++#define RPI_STATUS 56 ++#define RPI_VERSION 60 ++#define RPI_BFBASE 64 ++#define RPI_BFNUM 68 ++#define RPI_BFCONTROL 72 ++#define RPI_BFSTATUS 76 ++#define RPI_PUWBASE 80 ++#define RPI_PUWSTRIDE 84 ++#define RPI_COEFFWBASE 88 ++#define RPI_COEFFWSTRIDE 92 ++#define RPI_SLICECMDS 96 ++#define RPI_BEGINTILEEND 100 ++#define RPI_TRANSFER 104 ++#define RPI_CFBASE 108 ++#define RPI_CFNUM 112 ++#define RPI_CFSTATUS 116 ++ ++#define RPI_PURBASE 0x8000 ++#define RPI_PURSTRIDE 0x8004 ++#define RPI_COEFFRBASE 0x8008 ++#define RPI_COEFFRSTRIDE 0x800C ++#define RPI_NUMROWS 0x8010 ++#define RPI_CONFIG2 0x8014 ++#define RPI_OUTYBASE 0x8018 ++#define RPI_OUTYSTRIDE 0x801C ++#define RPI_OUTCBASE 0x8020 ++#define RPI_OUTCSTRIDE 0x8024 ++#define RPI_STATUS2 0x8028 ++#define RPI_FRAMESIZE 0x802C ++#define RPI_MVBASE 0x8030 ++#define RPI_MVSTRIDE 0x8034 ++#define RPI_COLBASE 0x8038 ++#define RPI_COLSTRIDE 0x803C ++#define RPI_CURRPOC 0x8040 ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++struct FFM_PROB { ++ uint8_t sao_merge_flag [ 1]; ++ uint8_t sao_type_idx [ 1]; ++ uint8_t split_coding_unit_flag [ 3]; ++ uint8_t cu_transquant_bypass_flag [ 1]; ++ uint8_t skip_flag [ 3]; ++ uint8_t cu_qp_delta [ 3]; ++ uint8_t pred_mode_flag [ 1]; ++ uint8_t part_mode [ 4]; ++ uint8_t prev_intra_luma_pred_flag [ 1]; ++ uint8_t intra_chroma_pred_mode [ 2]; ++ uint8_t merge_flag [ 1]; ++ uint8_t merge_idx [ 1]; ++ uint8_t inter_pred_idc [ 5]; ++ uint8_t ref_idx_l0 [ 2]; ++ uint8_t ref_idx_l1 [ 2]; ++ uint8_t abs_mvd_greater0_flag [ 2]; ++ uint8_t abs_mvd_greater1_flag [ 2]; ++ uint8_t mvp_lx_flag [ 1]; ++ uint8_t no_residual_data_flag [ 1]; ++ uint8_t split_transform_flag [ 3]; ++ uint8_t cbf_luma [ 2]; ++ uint8_t cbf_cb_cr [ 4]; ++ uint8_t transform_skip_flag/*[][]*/ [ 2]; ++ uint8_t explicit_rdpcm_flag/*[][]*/ [ 2]; ++ uint8_t explicit_rdpcm_dir_flag/*[][]*/ [ 2]; ++ uint8_t last_significant_coeff_x_prefix [18]; ++ uint8_t last_significant_coeff_y_prefix [18]; ++ uint8_t significant_coeff_group_flag [ 4]; ++ uint8_t significant_coeff_flag [44]; ++ uint8_t coeff_abs_level_greater1_flag [24]; ++ uint8_t coeff_abs_level_greater2_flag [ 6]; ++ uint8_t log2_res_scale_abs [ 8]; ++ uint8_t res_scale_sign_flag [ 2]; ++ uint8_t cu_chroma_qp_offset_flag [ 1]; ++ uint8_t cu_chroma_qp_offset_idx [ 1]; ++} __attribute__((packed)); ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++struct RPI_PROB { ++ uint8_t SAO_MERGE_FLAG [ 1]; ++ uint8_t SAO_TYPE_IDX [ 1]; ++ uint8_t SPLIT_FLAG [ 3]; ++ uint8_t CU_SKIP_FLAG [ 3]; ++ uint8_t CU_TRANSQUANT_BYPASS_FLAG [ 1]; ++ uint8_t PRED_MODE [ 1]; ++ uint8_t PART_SIZE [ 4]; ++ uint8_t INTRA_PRED_MODE [ 1]; ++ uint8_t CHROMA_PRED_MODE [ 1]; ++ uint8_t MERGE_FLAG_EXT [ 1]; ++ uint8_t MERGE_IDX_EXT [ 1]; ++ uint8_t INTER_DIR [ 5]; ++ uint8_t REF_PIC [ 2]; ++ uint8_t MVP_IDX [ 1]; ++ uint8_t MVD [ 2]; ++ uint8_t QT_ROOT_CBF [ 1]; ++ uint8_t TRANS_SUBDIV_FLAG [ 3]; ++ uint8_t QT_CBF [ 6]; ++ uint8_t DQP [ 2]; ++ uint8_t ONE_FLAG [24]; ++ uint8_t LASTX [18]; ++ uint8_t LASTY [18]; ++ uint8_t SIG_CG_FLAG [ 4]; ++ uint8_t ABS_FLAG [ 6]; ++ uint8_t TRANSFORMSKIP_FLAG [ 2]; ++ uint8_t SIG_FLAG [42]; ++ uint8_t SIG_FLAG_unused [ 2]; ++} __attribute__((packed)); ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++struct RPI_CMD { ++ uint32_t addr; ++ uint32_t data; ++} __attribute__((packed)); ++ ++struct RPI_BIT { ++ int cmd; ++ const void *ptr; ++ int len; ++}; ++ ++////////////////////////////////////////////////////////////////////////////// ++ ++typedef struct RPI_T { ++struct RPI_BIT *bit_fifo; ++struct RPI_CMD *cmd_fifo; ++ int bit_len, bit_max; ++ int cmd_len, cmd_max; ++ int max_pu_msgs; ++ int max_coeff64; ++AVCodecContext *thread_avctx[MAX_THREADS]; ++ int thread_order[MAX_THREADS]; ++ int decode_order; ++ int phase1_order; ++ int phase2_order; ++pthread_mutex_t mutex_phase1; ++pthread_mutex_t mutex_phase2; ++ uint8_t scaling_factors[NUM_SCALING_FACTORS]; ++struct RPI_PROB probabilities; ++ int num_slice_msgs; ++ uint16_t slice_msgs[2*HEVC_MAX_REFS*8+3]; ++ int pubase64[MAX_THREADS]; ++ int pustep64; ++ int coeffbase64[MAX_THREADS]; ++ int coeffstep64; ++ int PicWidthInCtbsY; ++ int PicHeightInCtbsY; ++#ifdef AXI_BUFFERS ++ int lumabytes64; ++ int framebytes64; ++ int lumastride64; ++ int chromastride64; ++#endif ++ int mvframebytes64; ++ int mvstorage64; ++ int colstride64; ++ int mvstride64; ++ int colbase64[MAX_THREADS]; ++ int mvbase64[MAX_THREADS]; ++ uint32_t reg_slicestart; ++ int collocated_from_l0_flag; ++ int max_num_merge_cand; ++ int RefPicList[2][HEVC_MAX_REFS]; ++ int collocated_ref_idx; ++ int wpp_entry_x; ++ int wpp_entry_y; ++ ++ void * dl_handle; ++ void * id; ++ char * (* ctrl_ffmpeg_init) (const char *hwaccel_device, void **id); ++ void (* apb_write) (void *id, uint16_t addr, uint32_t data); ++ void (* apb_write_addr) (void *id, uint16_t addr, uint32_t data); ++ uint32_t (* apb_read) (void *id, uint16_t addr); ++ void (* apb_read_drop) (void *id, uint16_t addr); ++ void (* axi_write) (void *id, uint64_t addr, uint32_t size, const void *buf); ++ void (* axi_read_alloc) (void *id, uint32_t size); ++ void (* axi_read_tx) (void *id, uint64_t addr, uint32_t size); ++ void (* axi_read_rx) (void *id, uint32_t size, void *buf); ++ uint64_t (* axi_get_addr) (void *id); ++ void (* apb_dump_regs) (void *id, uint16_t addr, int num); ++ void (* axi_dump) (void *id, uint64_t addr, uint32_t size); ++ void (* axi_flush) (void *id, int mode); ++ void (* wait_interrupt) (void *id, int phase); ++ void (* ctrl_ffmpeg_free) (void *id); ++ ++} RPI_T; +diff --git a/libavcodec/rpi_mailbox.c b/libavcodec/rpi_mailbox.c +new file mode 100644 +index 0000000000..5f23e9b36c +--- /dev/null ++++ b/libavcodec/rpi_mailbox.c +@@ -0,0 +1,149 @@ ++/* ++Copyright (c) 2012, Broadcom Europe Ltd. ++All rights reserved. ++ ++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. ++ * Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ * Neither the name of the copyright holder nor the ++ names of its contributors may be used to endorse or promote products ++ derived from this software without specific prior written permission. ++ ++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 HOLDER 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. ++*/ ++ ++#if 1//defined(RPI) || defined (RPI_DISPLAY) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define MAJOR_NUM 100 ++#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) ++#define DEVICE_FILE_NAME "/dev/vcio" ++ ++#include "rpi_mailbox.h" ++//#include ++ ++/* ++ * use ioctl to send mbox property message ++ */ ++ ++static int mbox_property(int file_desc, void *buf) ++{ ++ int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf); ++ ++ if (ret_val < 0) { ++ printf("ioctl_set_msg failed:%d\n", ret_val); ++ } ++ ++#ifdef DEBUG ++ unsigned *p = buf; int i; unsigned size = *(unsigned *)buf; ++ for (i=0; i ++#include ++#include ++#include ++#include ++#include "libavutil/avassert.h" ++ ++#include "config.h" ++ ++#include ++#include ++ ++#include ++ ++#include "rpi_mailbox.h" ++#include "rpi_qpu.h" ++ ++#pragma GCC diagnostic push ++// Many many redundant decls in the header files ++#pragma GCC diagnostic ignored "-Wredundant-decls" ++#include "interface/vmcs_host/vc_vchi_gpuserv.h" ++#pragma GCC diagnostic pop ++ ++// QPU "noflush" flags ++// a mixture of flushing & profiling ++ ++#define QPU_FLAGS_NO_FLUSH_VPU 1 // If unset VPU cache will be flushed ++#define QPU_FLAGS_PROF_CLEAR_AND_ENABLE 2 // Clear & Enable detailed QPU profiling registers ++#define QPU_FLAGS_PROF_OUTPUT_COUNTS 4 // Print the results ++#define QPU_FLAGS_OUTPUT_QPU_TIMES 8 // Print QPU times - independant of the profiling ++#define QPU_FLAGS_NO_FLUSH_QPU 16 // If unset flush QPU caches & TMUs (uniforms always flushed) ++ ++#define vcos_verify_ge0(x) ((x)>=0) ++ ++struct rpi_cache_flush_env_s { ++// unsigned int n; ++// struct vcsm_user_clean_invalid_s a[CFE_A_COUNT]; ++ struct vcsm_user_clean_invalid2_s v; ++}; ++ ++typedef struct gpu_env_s ++{ ++ int open_count; ++ int init_count; ++ int mb; ++ int vpu_i_cache_flushed; ++} gpu_env_t; ++ ++// Stop more than one thread trying to allocate memory or use the processing resources at once ++static pthread_mutex_t gpu_mutex = PTHREAD_MUTEX_INITIALIZER; ++static gpu_env_t * gpu = NULL; ++ ++ ++// GPU memory alloc fns (internal) ++ ++// GPU_MEM_PTR_T alloc fns ++static int gpu_malloc_cached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { ++ p->numbytes = (numbytes + 255) & ~255; // Round up ++ p->vcsm_handle = vcsm_malloc_cache(p->numbytes, VCSM_CACHE_TYPE_HOST | 0x80, (char *)"Video Frame" ); ++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_VC, (char *)"Video Frame" ); ++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE, (char *)"Video Frame" ); ++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_HOST_AND_VC, (char *)"Video Frame" ); ++ av_assert0(p->vcsm_handle); ++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); ++ av_assert0(p->vc_handle); ++ p->arm = vcsm_lock(p->vcsm_handle); ++ av_assert0(p->arm); ++ p->vc = mbox_mem_lock(mb, p->vc_handle); ++ av_assert0(p->vc); ++// printf("***** %s, %d\n", __func__, numbytes); ++ ++ return 0; ++} ++ ++static int gpu_malloc_uncached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { ++ p->numbytes = numbytes; ++ p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE | 0x80, (char *)"Video Frame" ); ++ av_assert0(p->vcsm_handle); ++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); ++ av_assert0(p->vc_handle); ++ p->arm = vcsm_lock(p->vcsm_handle); ++ av_assert0(p->arm); ++ p->vc = mbox_mem_lock(mb, p->vc_handle); ++ av_assert0(p->vc); ++// printf("***** %s, %d\n", __func__, numbytes); ++ return 0; ++} ++ ++static void gpu_free_internal(const int mb, GPU_MEM_PTR_T * const p) { ++ mbox_mem_unlock(mb, p->vc_handle); ++ vcsm_unlock_ptr(p->arm); ++ vcsm_free(p->vcsm_handle); ++ memset(p, 0, sizeof(*p)); // Ensure we crash hard if we try and use this again ++// printf("***** %s\n", __func__); ++} ++ ++ ++// GPU init, free, lock, unlock ++ ++static void gpu_term(void) ++{ ++ gpu_env_t * const ge = gpu; ++ ++ // We have to hope that eveything has terminated... ++ gpu = NULL; ++ ++ vc_gpuserv_deinit(); ++ ++ vcsm_exit(); ++ ++ mbox_close(ge->mb); ++ ++ free(ge); ++} ++ ++ ++// Connect to QPU, returns 0 on success. ++static int gpu_init(gpu_env_t ** const gpu) { ++ gpu_env_t * const ge = calloc(1, sizeof(gpu_env_t)); ++ *gpu = NULL; ++ ++ if (ge == NULL) ++ return -1; ++ ++ if ((ge->mb = mbox_open()) < 0) ++ return -1; ++ ++ vcsm_init(); ++ ++ *gpu = ge; ++ return 0; ++} ++ ++ ++ ++static void gpu_unlock(void) { ++ pthread_mutex_unlock(&gpu_mutex); ++} ++ ++// Make sure we have exclusive access to the mailbox, and enable qpu if necessary. ++static gpu_env_t * gpu_lock(void) { ++ pthread_mutex_lock(&gpu_mutex); ++ ++ av_assert0(gpu != NULL); ++ return gpu; ++} ++ ++static gpu_env_t * gpu_lock_ref(void) ++{ ++ pthread_mutex_lock(&gpu_mutex); ++ ++ if (gpu == NULL) { ++ int rv = gpu_init(&gpu); ++ if (rv != 0) { ++ gpu_unlock(); ++ return NULL; ++ } ++ } ++ ++ ++gpu->open_count; ++ return gpu; ++} ++ ++static void gpu_unlock_unref(gpu_env_t * const ge) ++{ ++ if (--ge->open_count == 0) ++ gpu_term(); ++ ++ gpu_unlock(); ++} ++ ++static inline gpu_env_t * gpu_ptr(void) ++{ ++ av_assert0(gpu != NULL); ++ return gpu; ++} ++ ++// Public gpu fns ++ ++// Allocate memory on GPU ++// Fills in structure

containing ARM pointer, videocore handle, videocore memory address, numbytes ++// Returns 0 on success. ++// This allocates memory that will not be cached in ARM's data cache. ++// Therefore safe to use without data cache flushing. ++int gpu_malloc_uncached(int numbytes, GPU_MEM_PTR_T *p) ++{ ++ int r; ++ gpu_env_t * const ge = gpu_lock_ref(); ++ if (ge == NULL) ++ return -1; ++ r = gpu_malloc_uncached_internal(ge->mb, numbytes, p); ++ gpu_unlock(); ++ return r; ++} ++ ++// This allocates data that will be ++// Cached in ARM L2 ++// Uncached in VPU L2 ++int gpu_malloc_cached(int numbytes, GPU_MEM_PTR_T *p) ++{ ++ int r; ++ gpu_env_t * const ge = gpu_lock_ref(); ++ if (ge == NULL) ++ return -1; ++ r = gpu_malloc_cached_internal(ge->mb, numbytes, p); ++ gpu_unlock(); ++ return r; ++} ++ ++void gpu_free(GPU_MEM_PTR_T * const p) { ++ gpu_env_t * const ge = gpu_lock(); ++ gpu_free_internal(ge->mb, p); ++ gpu_unlock_unref(ge); ++} ++ ++int gpu_get_mailbox(void) ++{ ++ av_assert0(gpu); ++ return gpu->mb; ++} ++ ++void gpu_ref(void) ++{ ++ gpu_lock_ref(); ++ gpu_unlock(); ++} ++ ++void gpu_unref(void) ++{ ++ gpu_env_t * const ge = gpu_lock(); ++ gpu_unlock_unref(ge); ++} ++ ++// ---------------------------------------------------------------------------- ++// ++// Cache flush functions ++ ++#define CACHE_EL_MAX 16 ++ ++rpi_cache_flush_env_t * rpi_cache_flush_init() ++{ ++ rpi_cache_flush_env_t * const rfe = malloc(sizeof(rpi_cache_flush_env_t) + ++ sizeof(struct vcsm_user_clean_invalid2_block_s) * CACHE_EL_MAX); ++ if (rfe == NULL) ++ return NULL; ++ ++ rfe->v.op_count = 0; ++ return rfe; ++} ++ ++void rpi_cache_flush_abort(rpi_cache_flush_env_t * const rfe) ++{ ++ if (rfe != NULL) ++ free(rfe); ++} ++ ++int rpi_cache_flush_finish(rpi_cache_flush_env_t * const rfe) ++{ ++ int rc = 0; ++ ++ if (vcsm_clean_invalid2(&rfe->v) != 0) ++ rc = -1; ++ ++ free(rfe); ++ ++ if (rc == 0) ++ return 0; ++ ++ av_log(NULL, AV_LOG_ERROR, "vcsm_clean_invalid failed: errno=%d\n", errno); ++ return rc; ++} ++ ++inline void rpi_cache_flush_add_gm_blocks(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, ++ const unsigned int offset0, const unsigned int block_size, const unsigned int blocks, const unsigned int block_stride) ++{ ++ struct vcsm_user_clean_invalid2_block_s * const b = rfe->v.s + rfe->v.op_count++; ++ ++ av_assert0(rfe->v.op_count <= CACHE_EL_MAX); ++ ++ b->invalidate_mode = mode; ++ b->block_count = blocks; ++ b->start_address = gm->arm + offset0; ++ b->block_size = block_size; ++ b->inter_block_stride = block_stride; ++} ++ ++void rpi_cache_flush_add_gm_range(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, ++ const unsigned int offset, const unsigned int size) ++{ ++ // Deal with empty pointer trivially ++ if (gm == NULL || size == 0) ++ return; ++ ++ av_assert0(offset <= gm->numbytes); ++ av_assert0(size <= gm->numbytes); ++ av_assert0(offset + size <= gm->numbytes); ++ ++ rpi_cache_flush_add_gm_blocks(rfe, gm, mode, offset, size, 1, 0); ++} ++ ++void rpi_cache_flush_add_gm_ptr(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode) ++{ ++ rpi_cache_flush_add_gm_blocks(rfe, gm, mode, 0, gm->numbytes, 1, 0); ++} ++ ++ ++void rpi_cache_flush_add_frame(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const unsigned int mode) ++{ ++#if !RPI_ONE_BUF ++#error Fixme! (NIF) ++#endif ++ if (gpu_is_buf1(frame)) { ++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf1_gmem(frame), mode); ++ } ++ else ++ { ++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 0), mode); ++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 1), mode); ++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 2), mode); ++ } ++} ++ ++// Call this to clean and invalidate a region of memory ++void rpi_cache_flush_one_gm_ptr(const GPU_MEM_PTR_T *const p, const rpi_cache_flush_mode_t mode) ++{ ++ rpi_cache_flush_env_t * rfe = rpi_cache_flush_init(); ++ rpi_cache_flush_add_gm_ptr(rfe, p, mode); ++ rpi_cache_flush_finish(rfe); ++} ++ ++ ++// ---------------------------------------------------------------------------- ++ ++#endif // RPI +diff --git a/libavcodec/rpi_qpu.h b/libavcodec/rpi_qpu.h +new file mode 100644 +index 0000000000..485a08f8ba +--- /dev/null ++++ b/libavcodec/rpi_qpu.h +@@ -0,0 +1,206 @@ ++#ifndef RPI_QPU_H ++#define RPI_QPU_H ++ ++#define RPI_ONE_BUF 1 ++ ++typedef struct gpu_mem_ptr_s { ++ unsigned char *arm; // Pointer to memory mapped on ARM side ++ int vc_handle; // Videocore handle of relocatable memory ++ int vcsm_handle; // Handle for use by VCSM ++ int vc; // Address for use in GPU code ++ int numbytes; // Size of memory block ++} GPU_MEM_PTR_T; ++ ++// General GPU functions ++extern int gpu_malloc_cached(int numbytes, GPU_MEM_PTR_T *p); ++extern int gpu_malloc_uncached(int numbytes, GPU_MEM_PTR_T *p); ++extern void gpu_free(GPU_MEM_PTR_T * const p); ++ ++#include "libavutil/frame.h" ++#if !RPI_ONE_BUF ++static inline uint32_t get_vc_address_y(const AVFrame * const frame) { ++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[0]); ++ return p->vc; ++} ++ ++static inline uint32_t get_vc_address_u(const AVFrame * const frame) { ++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[1]); ++ return p->vc; ++} ++ ++static inline uint32_t get_vc_address_v(const AVFrame * const frame) { ++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[2]); ++ return p->vc; ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_y(const AVFrame * const frame) { ++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[0]); ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_u(const AVFrame * const frame) { ++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[1]); ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_v(const AVFrame * const frame) { ++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[2]); ++} ++ ++#else ++ ++static inline int gpu_is_buf1(const AVFrame * const frame) ++{ ++ return frame->buf[1] == NULL; ++} ++ ++static inline GPU_MEM_PTR_T * gpu_buf1_gmem(const AVFrame * const frame) ++{ ++ return av_buffer_get_opaque(frame->buf[0]); ++} ++ ++static inline GPU_MEM_PTR_T * gpu_buf3_gmem(const AVFrame * const frame, const unsigned int n) ++{ ++ return av_buffer_pool_opaque(frame->buf[n]); ++} ++ ++static inline uint32_t get_vc_address3(const AVFrame * const frame, const unsigned int n) ++{ ++ const GPU_MEM_PTR_T * const gm = gpu_is_buf1(frame) ? gpu_buf1_gmem(frame) : gpu_buf3_gmem(frame, n); ++ return gm->vc + (frame->data[n] - gm->arm); ++} ++ ++ ++static inline uint32_t get_vc_address_y(const AVFrame * const frame) { ++ return get_vc_address3(frame, 0); ++} ++ ++static inline uint32_t get_vc_address_u(const AVFrame * const frame) { ++ return get_vc_address3(frame, 1); ++} ++ ++static inline uint32_t get_vc_address_v(const AVFrame * const frame) { ++ return get_vc_address3(frame, 2); ++} ++ ++#if 0 ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_y(const AVFrame * const frame) { ++ if (gpu_is_buf1(frame)) ++ { ++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); ++ g.numbytes = frame->data[1] - frame->data[0]; ++ return g; ++ } ++ else ++ return *gpu_buf3_gmem(frame, 0); ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_u(const AVFrame * const frame) { ++ if (gpu_is_buf1(frame)) ++ { ++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); ++ g.arm += frame->data[1] - frame->data[0]; ++ g.vc += frame->data[1] - frame->data[0]; ++ g.numbytes = frame->data[2] - frame->data[1]; // chroma size ++ return g; ++ } ++ else ++ return *gpu_buf3_gmem(frame, 1); ++} ++ ++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_v(const AVFrame * const frame) { ++ if (gpu_is_buf1(frame)) ++ { ++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); ++ g.arm += frame->data[2] - frame->data[0]; ++ g.vc += frame->data[2] - frame->data[0]; ++ g.numbytes = frame->data[2] - frame->data[1]; // chroma size ++ return g; ++ } ++ else ++ return *gpu_buf3_gmem(frame, 2); ++} ++#endif ++#endif ++ ++// Cache flush stuff ++ ++struct rpi_cache_flush_env_s; ++typedef struct rpi_cache_flush_env_s rpi_cache_flush_env_t; ++ ++rpi_cache_flush_env_t * rpi_cache_flush_init(void); ++// Free env without flushing ++void rpi_cache_flush_abort(rpi_cache_flush_env_t * const rfe); ++// Do the accumulated flush & free the env ++int rpi_cache_flush_finish(rpi_cache_flush_env_t * const rfe); ++ ++typedef enum ++{ ++ RPI_CACHE_FLUSH_MODE_INVALIDATE = 1, ++ RPI_CACHE_FLUSH_MODE_WRITEBACK = 2, ++ RPI_CACHE_FLUSH_MODE_WB_INVALIDATE = 3 ++} rpi_cache_flush_mode_t; ++ ++void rpi_cache_flush_add_gm_ptr(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const rpi_cache_flush_mode_t mode); ++void rpi_cache_flush_add_gm_range(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const rpi_cache_flush_mode_t mode, ++ const unsigned int offset, const unsigned int size); ++void rpi_cache_flush_add_gm_blocks(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, ++ const unsigned int offset0, const unsigned int block_size, const unsigned int blocks, const unsigned int block_stride); ++void rpi_cache_flush_add_frame(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const rpi_cache_flush_mode_t mode); ++void rpi_cache_flush_add_frame_block(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const rpi_cache_flush_mode_t mode, ++ const unsigned int x0, const unsigned int y0, const unsigned int width, const unsigned int height, ++ const unsigned int uv_shift, const int do_luma, const int do_chroma); ++ ++// init, add, finish for one gm ptr ++void rpi_cache_flush_one_gm_ptr(const GPU_MEM_PTR_T * const p, const rpi_cache_flush_mode_t mode); ++ ++ ++// QPU specific functions ++ ++typedef struct HEVCRpiQpu { ++ uint32_t c_pxx; ++ uint32_t c_pxx_l1; ++ uint32_t c_bxx; ++ uint32_t y_pxx; ++ uint32_t y_bxx; ++ uint32_t y_p00; ++ uint32_t y_b00; ++} HEVCRpiQpu; ++ ++int rpi_hevc_qpu_init_fn(HEVCRpiQpu * const qf, const unsigned int bit_depth); ++ ++uint32_t qpu_fn(const int * const mc_fn); ++ ++#define QPU_N_GRP 4 ++#define QPU_N_MAX 12 ++ ++#define QPU_MAIL_EL_VALS 2 ++ ++struct vpu_qpu_wait_s; ++typedef struct vq_wait_s * vpu_qpu_wait_h; ++ ++// VPU specific functions ++ ++struct vpu_qpu_job_env_s; ++typedef struct vpu_qpu_job_env_s * vpu_qpu_job_h; ++ ++vpu_qpu_job_h vpu_qpu_job_new(void); ++void vpu_qpu_job_delete(const vpu_qpu_job_h vqj); ++void vpu_qpu_job_add_vpu(const vpu_qpu_job_h vqj, const uint32_t vpu_code, ++ const unsigned r0, const unsigned r1, const unsigned r2, const unsigned r3, const unsigned r4, const unsigned r5); ++void vpu_qpu_job_add_qpu(const vpu_qpu_job_h vqj, const unsigned int n, const uint32_t * const mail); ++void vpu_qpu_job_add_sync_this(const vpu_qpu_job_h vqj, vpu_qpu_wait_h * const wait_h); ++int vpu_qpu_job_start(const vpu_qpu_job_h vqj); ++int vpu_qpu_job_finish(const vpu_qpu_job_h vqj); ++ ++extern unsigned int vpu_get_fn(const unsigned int bit_depth); ++extern unsigned int vpu_get_constants(void); ++ ++// Waits for previous post_codee to complete and Will null out *wait_h after use ++void vpu_qpu_wait(vpu_qpu_wait_h * const wait_h); ++int vpu_qpu_init(void); ++void vpu_qpu_term(void); ++ ++extern int gpu_get_mailbox(void); ++void gpu_ref(void); ++void gpu_unref(void); ++ ++#endif +diff --git a/libavcodec/rpi_zc.c b/libavcodec/rpi_zc.c +new file mode 100644 +index 0000000000..3bf1da4083 +--- /dev/null ++++ b/libavcodec/rpi_zc.c +@@ -0,0 +1,743 @@ ++#include "config.h" ++#if 1 //defined(RPI) //|| defined (RPI_DISPLAY) ++#include "libavcodec/avcodec.h" ++#include "rpi_qpu.h" ++#include "rpi_mailbox.h" ++#include "rpi_zc.h" ++#include "libavutil/avassert.h" ++#include ++ ++#include "libavutil/buffer_internal.h" ++#include ++ ++#define TRACE_ALLOC 0 ++ ++struct ZcPoolEnt; ++ ++typedef struct ZcPool ++{ ++ int numbytes; ++ unsigned int n; ++ struct ZcPoolEnt * head; ++ pthread_mutex_t lock; ++} ZcPool; ++ ++typedef struct ZcPoolEnt ++{ ++ // It is important that we start with gmem as other bits of code will expect to see that ++ GPU_MEM_PTR_T gmem; ++ unsigned int n; ++ struct ZcPoolEnt * next; ++ struct ZcPool * pool; ++} ZcPoolEnt; ++ ++#define ALLOC_PAD 0 ++#define ALLOC_ROUND 0x1000 ++#define ALLOC_N_OFFSET 0 ++#define STRIDE_ROUND 64 ++#define STRIDE_OR 0 ++ ++#define DEBUG_ZAP0_BUFFERS 0 ++ ++static inline int av_rpi_is_sand_format(const int format) ++{ ++ return (format >= AV_PIX_FMT_SAND128 && format <= AV_PIX_FMT_SAND64_16) || ++ (format == AV_PIX_FMT_RPI4_8 || format == AV_PIX_FMT_RPI4_10); ++} ++ ++static inline int av_rpi_is_sand_frame(const AVFrame * const frame) ++{ ++ return av_rpi_is_sand_format(frame->format); ++} ++ ++static ZcPoolEnt * zc_pool_ent_alloc(ZcPool * const pool, const unsigned int req_size) ++{ ++ ZcPoolEnt * const zp = av_malloc(sizeof(ZcPoolEnt)); ++ ++ // Round up to 4k & add 4k ++ const unsigned int alloc_size = (req_size + ALLOC_PAD + ALLOC_ROUND - 1) & ~(ALLOC_ROUND - 1); ++ ++ if (zp == NULL) { ++ av_log(NULL, AV_LOG_ERROR, "av_malloc(ZcPoolEnt) failed\n"); ++ goto fail0; ++ } ++ ++ if (gpu_malloc_cached(alloc_size, &zp->gmem) != 0) ++ { ++ av_log(NULL, AV_LOG_ERROR, "av_gpu_malloc_cached(%d) failed\n", alloc_size); ++ goto fail1; ++ } ++ ++#if TRACE_ALLOC ++ printf("%s: Alloc %#x bytes @ %p\n", __func__, zp->gmem.numbytes, zp->gmem.arm); ++#endif ++ ++ pool->numbytes = zp->gmem.numbytes; ++ zp->next = NULL; ++ zp->pool = pool; ++ zp->n = pool->n++; ++ return zp; ++ ++fail1: ++ av_free(zp); ++fail0: ++ return NULL; ++} ++ ++static void zc_pool_ent_free(ZcPoolEnt * const zp) ++{ ++#if TRACE_ALLOC ++ printf("%s: Free %#x bytes @ %p\n", __func__, zp->gmem.numbytes, zp->gmem.arm); ++#endif ++ ++ gpu_free(&zp->gmem); ++ av_free(zp); ++} ++ ++static void zc_pool_flush(ZcPool * const pool) ++{ ++ ZcPoolEnt * p = pool->head; ++ pool->head = NULL; ++ pool->numbytes = -1; ++ ++ while (p != NULL) ++ { ++ ZcPoolEnt * const zp = p; ++ p = p->next; ++ zc_pool_ent_free(zp); ++ } ++} ++ ++static ZcPoolEnt * zc_pool_alloc(ZcPool * const pool, const int req_bytes) ++{ ++ ZcPoolEnt * zp; ++ int numbytes; ++ ++ pthread_mutex_lock(&pool->lock); ++ ++ numbytes = pool->numbytes; ++ ++ // If size isn't close then dump the pool ++ // Close in this context means within 128k ++ if (req_bytes > numbytes || req_bytes + 0x20000 < numbytes) ++ { ++ zc_pool_flush(pool); ++ numbytes = req_bytes; ++ } ++ ++ if (pool->head != NULL) ++ { ++ zp = pool->head; ++ pool->head = zp->next; ++ } ++ else ++ { ++ zp = zc_pool_ent_alloc(pool, numbytes); ++ } ++ ++ pthread_mutex_unlock(&pool->lock); ++ ++ // Start with our buffer empty of preconceptions ++// rpi_cache_flush_one_gm_ptr(&zp->gmem, RPI_CACHE_FLUSH_MODE_INVALIDATE); ++ ++ return zp; ++} ++ ++static void zc_pool_free(ZcPoolEnt * const zp) ++{ ++ ZcPool * const pool = zp == NULL ? NULL : zp->pool; ++ if (zp != NULL) ++ { ++ pthread_mutex_lock(&pool->lock); ++#if TRACE_ALLOC ++ printf("%s: Recycle %#x, %#x\n", __func__, pool->numbytes, zp->gmem.numbytes); ++#endif ++ ++ if (pool->numbytes == zp->gmem.numbytes) ++ { ++ zp->next = pool->head; ++ pool->head = zp; ++ pthread_mutex_unlock(&pool->lock); ++ } ++ else ++ { ++ pthread_mutex_unlock(&pool->lock); ++ zc_pool_ent_free(zp); ++ } ++ } ++} ++ ++static void ++zc_pool_init(ZcPool * const pool) ++{ ++ pool->numbytes = -1; ++ pool->head = NULL; ++ pthread_mutex_init(&pool->lock, NULL); ++} ++ ++static void ++zc_pool_destroy(ZcPool * const pool) ++{ ++ pool->numbytes = -1; ++ zc_pool_flush(pool); ++ pthread_mutex_destroy(&pool->lock); ++} ++ ++typedef struct ZcOldCtxVals ++{ ++ int thread_safe_callbacks; ++ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); ++ void * get_buffer_context; ++} ZcOldCtxVals; ++ ++typedef struct AVZcEnv ++{ ++ unsigned int refcount; ++ ZcPool pool; ++ ZcOldCtxVals old; ++} ZcEnv; ++ ++// Callback when buffer unrefed to zero ++static void rpi_free_display_buffer(void *opaque, uint8_t *data) ++{ ++ ZcPoolEnt *const zp = opaque; ++// printf("%s: data=%p\n", __func__, data); ++ zc_pool_free(zp); ++} ++ ++static inline GPU_MEM_PTR_T * pic_gm_ptr(AVBufferRef * const buf) ++{ ++ // Kludge where we check the free fn to check this is really ++ // one of our buffers - can't think of a better way ++ return buf == NULL || buf->buffer->free != rpi_free_display_buffer ? NULL : ++ av_buffer_get_opaque(buf); ++} ++ ++AVRpiZcFrameGeometry av_rpi_zc_frame_geometry( ++ const int format, const unsigned int video_width, const unsigned int video_height) ++{ ++ AVRpiZcFrameGeometry geo; ++ ++ switch (format) ++ { ++ case AV_PIX_FMT_YUV420P: ++ geo.stride_y = ((video_width + 32 + STRIDE_ROUND - 1) & ~(STRIDE_ROUND - 1)) | STRIDE_OR; ++ geo.stride_c = geo.stride_y / 2; ++ geo.height_y = (video_height + 32 + 31) & ~31; ++ geo.height_c = geo.height_y / 2; ++ geo.planes_c = 2; ++ geo.stripes = 1; ++ geo.bytes_per_pel = 1; ++ geo.stripe_is_yc = 1; ++ break; ++ ++ case AV_PIX_FMT_YUV420P10: ++ geo.stride_y = ((video_width * 2 + 64 + STRIDE_ROUND - 1) & ~(STRIDE_ROUND - 1)) | STRIDE_OR; ++ geo.stride_c = geo.stride_y / 2; ++ geo.height_y = (video_height + 32 + 31) & ~31; ++ geo.height_c = geo.height_y / 2; ++ geo.planes_c = 2; ++ geo.stripes = 1; ++ geo.bytes_per_pel = 2; ++ geo.stripe_is_yc = 1; ++ break; ++ ++ case AV_PIX_FMT_SAND128: ++ case AV_PIX_FMT_RPI4_8: ++ { ++ const unsigned int stripe_w = 128; ++ ++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; ++ static VC_IMAGE_T img = {0}; ++ ++ // Given the overhead of calling the mailbox keep a stashed ++ // copy as we will almost certainly just want the same numbers again ++ // but that means we need a lock ++ pthread_mutex_lock(&sand_lock); ++ ++ if (img.width != video_width || img.height != video_height) ++ { ++ VC_IMAGE_T new_img = { ++ .type = VC_IMAGE_YUV_UV, ++ .width = video_width, ++ .height = video_height ++ }; ++ ++ gpu_ref(); ++ mbox_get_image_params(gpu_get_mailbox(), &new_img); ++ gpu_unref(); ++ img = new_img; ++ } ++ ++ geo.stride_y = stripe_w; ++ geo.stride_c = stripe_w; ++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; ++ geo.height_c = img.pitch / stripe_w - geo.height_y; ++ geo.stripe_is_yc = 1; ++ if (geo.height_y * stripe_w > img.pitch) ++ { ++ // "tall" sand - all C blocks now follow Y ++ geo.height_y = img.pitch / stripe_w; ++ geo.height_c = geo.height_y; ++ geo.stripe_is_yc = 0; ++ } ++ geo.planes_c = 1; ++ geo.stripes = (video_width + stripe_w - 1) / stripe_w; ++ geo.bytes_per_pel = 1; ++ ++ pthread_mutex_unlock(&sand_lock); ++#if 0 ++ printf("Req: %dx%d: stride=%d/%d, height=%d/%d, stripes=%d, img.pitch=%d\n", ++ video_width, video_height, ++ geo.stride_y, geo.stride_c, ++ geo.height_y, geo.height_c, ++ geo.stripes, img.pitch); ++#endif ++ av_assert0((int)geo.height_y > 0 && (int)geo.height_c > 0); ++ av_assert0(geo.height_y >= video_height && geo.height_c >= video_height / 2); ++ break; ++ } ++ ++ case AV_PIX_FMT_RPI4_10: ++ { ++ const unsigned int stripe_w = 128; // bytes ++ ++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; ++ static VC_IMAGE_T img = {0}; ++ ++ // Given the overhead of calling the mailbox keep a stashed ++ // copy as we will almost certainly just want the same numbers again ++ // but that means we need a lock ++ pthread_mutex_lock(&sand_lock); ++ ++ if (img.width != video_width || img.height != video_height) ++ { ++ VC_IMAGE_T new_img = { ++ .type = VC_IMAGE_YUV10COL, ++ .width = video_width, ++ .height = video_height ++ }; ++ ++ gpu_ref(); ++ mbox_get_image_params(gpu_get_mailbox(), &new_img); ++ gpu_unref(); ++ img = new_img; ++ } ++ ++ geo.stride_y = stripe_w; ++ geo.stride_c = stripe_w; ++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; ++ geo.height_c = img.pitch / stripe_w - geo.height_y; ++ geo.planes_c = 1; ++ geo.stripes = ((video_width * 4 + 2) / 3 + stripe_w - 1) / stripe_w; ++ geo.bytes_per_pel = 1; ++ geo.stripe_is_yc = 1; ++ ++ pthread_mutex_unlock(&sand_lock); ++ ++ av_assert0((int)geo.height_y > 0 && (int)geo.height_c > 0); ++ av_assert0(geo.height_y >= video_height && geo.height_c >= video_height / 2); ++ break; ++ } ++ ++ case AV_PIX_FMT_SAND64_16: ++ case AV_PIX_FMT_SAND64_10: ++ { ++ const unsigned int stripe_w = 128; // bytes ++ ++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; ++ static VC_IMAGE_T img = {0}; ++ ++ // Given the overhead of calling the mailbox keep a stashed ++ // copy as we will almost certainly just want the same numbers again ++ // but that means we need a lock ++ pthread_mutex_lock(&sand_lock); ++ ++ if (img.width != video_width || img.height != video_height) ++ { ++ VC_IMAGE_T new_img = { ++ .type = VC_IMAGE_YUV_UV_16, ++ .width = video_width, ++ .height = video_height ++ }; ++ ++ gpu_ref(); ++ mbox_get_image_params(gpu_get_mailbox(), &new_img); ++ gpu_unref(); ++ img = new_img; ++ } ++ ++ geo.stride_y = stripe_w; ++ geo.stride_c = stripe_w; ++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; ++ geo.height_c = img.pitch / stripe_w - geo.height_y; ++ geo.planes_c = 1; ++ geo.stripes = (video_width * 2 + stripe_w - 1) / stripe_w; ++ geo.bytes_per_pel = 2; ++ geo.stripe_is_yc = 1; ++ ++ pthread_mutex_unlock(&sand_lock); ++ break; ++ } ++ ++ default: ++ memset(&geo, 0, sizeof(geo)); ++ break; ++ } ++ return geo; ++} ++ ++ ++static AVBufferRef * rpi_buf_pool_alloc(ZcPool * const pool, int size) ++{ ++ ZcPoolEnt *const zp = zc_pool_alloc(pool, size); ++ AVBufferRef * buf; ++ intptr_t idata = (intptr_t)zp->gmem.arm; ++#if ALLOC_N_OFFSET != 0 ++ intptr_t noff = (zp->n * ALLOC_N_OFFSET) & (ALLOC_PAD - 1); ++#endif ++ ++ if (zp == NULL) { ++ av_log(NULL, AV_LOG_ERROR, "zc_pool_alloc(%d) failed\n", size); ++ goto fail0; ++ } ++ ++#if ALLOC_N_OFFSET != 0 ++ idata = ((idata & ~(ALLOC_PAD - 1)) | noff) + (((idata & (ALLOC_PAD - 1)) > noff) ? ALLOC_PAD : 0); ++#endif ++ ++#if DEBUG_ZAP0_BUFFERS ++ memset((void*)idata, 0, size); ++#endif ++ ++ if ((buf = av_buffer_create((void *)idata, size, rpi_free_display_buffer, zp, AV_BUFFER_FLAG_READONLY)) == NULL) ++ { ++ av_log(NULL, AV_LOG_ERROR, "av_buffer_create() failed\n"); ++ goto fail2; ++ } ++ ++ return buf; ++ ++fail2: ++ zc_pool_free(zp); ++fail0: ++ return NULL; ++} ++ ++static int rpi_get_display_buffer(ZcEnv *const zc, AVFrame * const frame) ++{ ++ const AVRpiZcFrameGeometry geo = av_rpi_zc_frame_geometry(frame->format, frame->width, frame->height); ++ const unsigned int size_y = geo.stride_y * geo.height_y; ++ const unsigned int size_c = geo.stride_c * geo.height_c; ++ const unsigned int size_pic = (size_y + size_c * geo.planes_c) * geo.stripes; ++ AVBufferRef * buf; ++ unsigned int i; ++ ++// printf("Do local alloc: format=%#x, %dx%d: %u\n", frame->format, frame->width, frame->height, size_pic); ++ ++ if ((buf = rpi_buf_pool_alloc(&zc->pool, size_pic)) == NULL) ++ { ++ av_log(NULL, AV_LOG_ERROR, "rpi_get_display_buffer: Failed to get buffer from pool\n"); ++ return AVERROR(ENOMEM); ++ } ++ ++ for (i = 0; i < AV_NUM_DATA_POINTERS; i++) { ++ frame->buf[i] = NULL; ++ frame->data[i] = NULL; ++ frame->linesize[i] = 0; ++ } ++ ++ frame->buf[0] = buf; ++ ++ frame->linesize[0] = geo.stride_y; ++ frame->linesize[1] = geo.stride_c; ++ frame->linesize[2] = geo.stride_c; ++ // abuse: linesize[3] = "stripe stride" ++ // stripe_stride is NOT the stride between slices it is (that / geo.stride_y). ++ // In a general case this makes the calculation an xor and multiply rather ++ // than a divide and multiply ++ if (geo.stripes > 1) ++ frame->linesize[3] = geo.stripe_is_yc ? geo.height_y + geo.height_c : geo.height_y; ++ ++ frame->data[0] = buf->data; ++ frame->data[1] = frame->data[0] + (geo.stripe_is_yc ? size_y : size_y * geo.stripes); ++ if (geo.planes_c > 1) ++ frame->data[2] = frame->data[1] + size_c; ++ ++ frame->extended_data = frame->data; ++ // Leave extended buf alone ++ ++#if RPI_ZC_SAND_8_IN_10_BUF != 0 ++ // *** If we intend to use this for real we will want a 2nd buffer pool ++ frame->buf[RPI_ZC_SAND_8_IN_10_BUF] = rpi_buf_pool_alloc(&zc->pool, size_pic); // *** 2 * wanted size - kludge ++#endif ++ ++ return 0; ++} ++ ++#define RPI_GET_BUFFER2 1 ++ ++int av_rpi_zc_get_buffer2(struct AVCodecContext *s, AVFrame *frame, int flags) ++{ ++#if !RPI_GET_BUFFER2 ++ return avcodec_default_get_buffer2(s, frame, flags); ++#else ++ int rv; ++ ++ if ((s->codec->capabilities & AV_CODEC_CAP_DR1) == 0) ++ { ++// printf("Do default alloc: format=%#x\n", frame->format); ++ rv = avcodec_default_get_buffer2(s, frame, flags); ++ } ++ else if (frame->format == AV_PIX_FMT_YUV420P || ++ av_rpi_is_sand_frame(frame)) ++ { ++ rv = rpi_get_display_buffer(s->get_buffer_context, frame); ++ } ++ else ++ { ++ rv = avcodec_default_get_buffer2(s, frame, flags); ++ } ++ ++#if 0 ++ printf("%s: fmt:%d, %dx%d lsize=%d/%d/%d/%d data=%p/%p/%p bref=%p/%p/%p opaque[0]=%p\n", __func__, ++ frame->format, frame->width, frame->height, ++ frame->linesize[0], frame->linesize[1], frame->linesize[2], frame->linesize[3], ++ frame->data[0], frame->data[1], frame->data[2], ++ frame->buf[0], frame->buf[1], frame->buf[2], ++ av_buffer_get_opaque(frame->buf[0])); ++#endif ++ return rv; ++#endif ++} ++ ++ ++static AVBufferRef * zc_copy(struct AVCodecContext * const s, ++ const AVFrame * const src) ++{ ++ AVFrame dest_frame; ++ AVFrame * const dest = &dest_frame; ++ unsigned int i; ++ uint8_t * psrc, * pdest; ++ ++ dest->format = src->format; ++ dest->width = src->width; ++ dest->height = src->height; ++ ++ if (rpi_get_display_buffer(s->get_buffer_context, dest) != 0) ++ { ++ return NULL; ++ } ++ ++ for (i = 0, psrc = src->data[0], pdest = dest->data[0]; ++ i != dest->height; ++ ++i, psrc += src->linesize[0], pdest += dest->linesize[0]) ++ { ++ memcpy(pdest, psrc, dest->width); ++ } ++ for (i = 0, psrc = src->data[1], pdest = dest->data[1]; ++ i != dest->height / 2; ++ ++i, psrc += src->linesize[1], pdest += dest->linesize[1]) ++ { ++ memcpy(pdest, psrc, dest->width / 2); ++ } ++ for (i = 0, psrc = src->data[2], pdest = dest->data[2]; ++ i != dest->height / 2; ++ ++i, psrc += src->linesize[2], pdest += dest->linesize[2]) ++ { ++ memcpy(pdest, psrc, dest->width / 2); ++ } ++ ++ return dest->buf[0]; ++} ++ ++ ++static AVBufferRef * zc_420p10_to_sand128(struct AVCodecContext * const s, ++ const AVFrame * const src) ++{ ++ assert(0); ++ return NULL; ++} ++ ++ ++static AVBufferRef * zc_sand64_16_to_sand128(struct AVCodecContext * const s, ++ const AVFrame * const src, const unsigned int src_bits) ++{ ++ assert(0); ++ return NULL; ++} ++ ++ ++ ++AVRpiZcRefPtr av_rpi_zc_ref(struct AVCodecContext * const s, ++ const AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy) ++{ ++ assert(s != NULL); ++ ++ if (frame->format != AV_PIX_FMT_YUV420P && ++ frame->format != AV_PIX_FMT_YUV420P10 && ++ !av_rpi_is_sand_frame(frame)) ++ { ++ av_log(s, AV_LOG_WARNING, "%s: *** Format not SAND/YUV420P: %d\n", __func__, frame->format); ++ return NULL; ++ } ++ ++ if (frame->buf[1] != NULL || frame->format != expected_format) ++ { ++#if RPI_ZC_SAND_8_IN_10_BUF ++ if (frame->format == AV_PIX_FMT_SAND64_10 && expected_format == AV_PIX_FMT_SAND128 && frame->buf[RPI_ZC_SAND_8_IN_10_BUF] != NULL) ++ { ++// av_log(s, AV_LOG_INFO, "%s: --- found buf[4]\n", __func__); ++ return av_buffer_ref(frame->buf[RPI_ZC_SAND_8_IN_10_BUF]); ++ } ++#endif ++ ++ if (maycopy) ++ { ++ if (frame->buf[1] != NULL) ++ av_log(s, AV_LOG_INFO, "%s: *** Not a single buf frame: copying\n", __func__); ++ else ++ av_log(s, AV_LOG_INFO, "%s: *** Unexpected frame format %d: copying to %d\n", __func__, frame->format, expected_format); ++ ++ switch (frame->format) ++ { ++ case AV_PIX_FMT_YUV420P10: ++ return zc_420p10_to_sand128(s, frame); ++ ++ case AV_PIX_FMT_SAND64_10: ++ return zc_sand64_16_to_sand128(s, frame, 10); ++ ++ default: ++ return zc_copy(s, frame); ++ } ++ } ++ else ++ { ++ if (frame->buf[1] != NULL) ++ av_log(s, AV_LOG_WARNING, "%s: *** Not a single buf frame: buf[1] != NULL\n", __func__); ++ else ++ av_log(s, AV_LOG_INFO, "%s: *** Unexpected frame format: %d != %d\n", __func__, frame->format, expected_format); ++ return NULL; ++ } ++ } ++ ++ if (pic_gm_ptr(frame->buf[0]) == NULL) ++ { ++ if (maycopy) ++ { ++ av_log(s, AV_LOG_INFO, "%s: *** Not one of our buffers: copying\n", __func__); ++ return zc_copy(s, frame); ++ } ++ else ++ { ++ av_log(s, AV_LOG_WARNING, "%s: *** Not one of our buffers: NULL\n", __func__); ++ return NULL; ++ } ++ } ++ ++ return av_buffer_ref(frame->buf[0]); ++} ++ ++int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref) ++{ ++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); ++ return p == NULL ? -1 : p->vc_handle; ++} ++ ++int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref) ++{ ++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); ++ return p == NULL ? 0 : fr_ref->data - p->arm; ++} ++ ++int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref) ++{ ++ return fr_ref == NULL ? 0 : fr_ref->size; ++} ++ ++ ++int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref) ++{ ++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); ++ return p == NULL ? 0 : p->numbytes; ++} ++ ++void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref) ++{ ++ if (fr_ref != NULL) ++ { ++ av_buffer_unref(&fr_ref); ++ } ++} ++ ++AVZcEnvPtr av_rpi_zc_env_alloc(void) ++{ ++ ZcEnv * const zc = av_mallocz(sizeof(ZcEnv)); ++ if (zc == NULL) ++ { ++ av_log(NULL, AV_LOG_ERROR, "av_rpi_zc_env_alloc: Context allocation failed\n"); ++ return NULL; ++ } ++ ++ zc_pool_init(&zc->pool); ++ return zc; ++} ++ ++void av_rpi_zc_env_free(AVZcEnvPtr zc) ++{ ++ if (zc != NULL) ++ { ++ zc_pool_destroy(&zc->pool); ; ++ av_free(zc); ++ } ++} ++ ++int av_rpi_zc_in_use(const struct AVCodecContext * const s) ++{ ++ return s->get_buffer2 == av_rpi_zc_get_buffer2; ++} ++ ++int av_rpi_zc_init(struct AVCodecContext * const s) ++{ ++ if (av_rpi_zc_in_use(s)) ++ { ++ ZcEnv * const zc = s->get_buffer_context; ++ ++zc->refcount; ++ } ++ else ++ { ++ ZcEnv *const zc = av_rpi_zc_env_alloc(); ++ if (zc == NULL) ++ { ++ return AVERROR(ENOMEM); ++ } ++ ++ zc->refcount = 1; ++ zc->old.get_buffer_context = s->get_buffer_context; ++ zc->old.get_buffer2 = s->get_buffer2; ++ zc->old.thread_safe_callbacks = s->thread_safe_callbacks; ++ ++ s->get_buffer_context = zc; ++ s->get_buffer2 = av_rpi_zc_get_buffer2; ++ s->thread_safe_callbacks = 1; ++ } ++ return 0; ++} ++ ++void av_rpi_zc_uninit(struct AVCodecContext * const s) ++{ ++ if (av_rpi_zc_in_use(s)) ++ { ++ ZcEnv * const zc = s->get_buffer_context; ++ if (--zc->refcount == 0) ++ { ++ s->get_buffer2 = zc->old.get_buffer2; ++ s->get_buffer_context = zc->old.get_buffer_context; ++ s->thread_safe_callbacks = zc->old.thread_safe_callbacks; ++ av_rpi_zc_env_free(zc); ++ } ++ } ++} ++ ++#endif // RPI ++ +diff --git a/libavcodec/rpi_zc.h b/libavcodec/rpi_zc.h +new file mode 100644 +index 0000000000..0e39b8e3b3 +--- /dev/null ++++ b/libavcodec/rpi_zc.h +@@ -0,0 +1,106 @@ ++#ifndef LIBAVCODEC_RPI_ZC_H ++#define LIBAVCODEC_RPI_ZC_H ++ ++// Zero-Copy frame code for RPi ++// RPi needs Y/U/V planes to be contiguous for display. By default ++// ffmpeg will allocate separated planes so a memcpy is needed before ++// display. This code provides a method a making ffmpeg allocate a single ++// bit of memory for the frame when can then be reference counted until ++// display has finished with it. ++ ++// Frame buffer number in which to stuff an 8-bit copy of a 16-bit frame ++// 0 disables ++// *** This option still in development ++// Only works if SAO active ++// Allocates buffers that are twice the required size ++#define RPI_ZC_SAND_8_IN_10_BUF 0 ++ ++struct AVBufferRef; ++struct AVFrame; ++struct AVCodecContext; ++enum AVPixelFormat; ++ ++// "Opaque" pointer to whatever we are using as a buffer reference ++typedef struct AVBufferRef * AVRpiZcRefPtr; ++ ++struct AVZcEnv; ++typedef struct AVZcEnv * AVZcEnvPtr; ++ ++typedef struct AVRpiZcFrameGeometry ++{ ++ unsigned int stride_y; // Luma stride (bytes) ++ unsigned int height_y; // Luma height (lines) ++ unsigned int stride_c; // Chroma stride (bytes) ++ unsigned int height_c; // Chroma stride (lines) ++ unsigned int planes_c; // Chroma plane count (U, V = 2, interleaved = 1) ++ unsigned int stripes; // Number of stripes (sand) ++ unsigned int bytes_per_pel; ++ int stripe_is_yc; // A single stripe is Y then C (false for tall sand) ++} AVRpiZcFrameGeometry; ++ ++ ++AVRpiZcFrameGeometry av_rpi_zc_frame_geometry( ++ const int format, ++ const unsigned int video_width, const unsigned int video_height); ++ ++// Replacement fn for avctx->get_buffer2 ++// Should be set before calling avcodec_decode_open2 ++// ++// N.B. in addition to to setting avctx->get_buffer2, avctx->refcounted_frames ++// must be set to 1 as otherwise the buffer info is killed before being returned ++// by avcodec_decode_video2. Note also that this means that the AVFrame that is ++// returned must be manually derefed with av_frame_unref. This should be done ++// after av_rpi_zc_ref has been called. ++int av_rpi_zc_get_buffer2(struct AVCodecContext *s, AVFrame *frame, int flags); ++ ++// Generate a ZC reference to the buffer(s) in this frame ++// If the buffer doesn't appear to be one allocated by _get_buffer_2 ++// then the behaviour depends on maycopy: ++// If maycopy=0 then return NULL ++// If maycopy=1 && the src frame is in a form where we can easily copy ++// the data, then allocate a new buffer and copy the data into it ++// Otherwise return NULL ++AVRpiZcRefPtr av_rpi_zc_ref(struct AVCodecContext * const s, ++ const struct AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy); ++ ++// Get the vc_handle from the frame ref ++// Returns -1 if ref doesn't look valid ++int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref); ++// Get offset from the start of the memory referenced ++// by the vc_handle to valid data ++int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref); ++// Length of buffer data ++int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref); ++// Get the number of bytes allocated from the frame ref ++// Returns 0 if ref doesn't look valid ++int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref); ++ ++// Unreference the buffer refed/allocated by _zc_ref ++// If fr_ref is NULL then this will NOP ++void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref); ++ ++// Allocate an environment for the buffer pool used by the ZC code ++// This should be put in avctx->get_buffer_context so it can be found by ++// av_rpi_zc_get_buffer2 when it is called from ffmpeg ++AVZcEnvPtr av_rpi_zc_env_alloc(void); ++ ++// Allocate the environment used by the ZC code ++void av_rpi_zc_env_free(AVZcEnvPtr); ++ ++// Test to see if the context is using zc (checks get_buffer2) ++int av_rpi_zc_in_use(const struct AVCodecContext * const s); ++ ++// Init ZC into a context ++// There is nothing magic in this fn - it just packages setting ++// get_buffer2 & get_buffer_context ++int av_rpi_zc_init(struct AVCodecContext * const s); ++ ++// Free ZC from a context ++// There is nothing magic in this fn - it just packages unsetting ++// get_buffer2 & get_buffer_context ++void av_rpi_zc_uninit(struct AVCodecContext * const s); ++ ++ ++ ++#endif ++ +diff --git a/libavutil/buffer.c b/libavutil/buffer.c +index 9c5d530c7a..e07f947cdc 100644 +--- a/libavutil/buffer.c ++++ b/libavutil/buffer.c +@@ -368,3 +368,9 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) + + return ret; + } ++ ++// Return the opaque for the underlying frame (gives us a GPU_MEM_PTR_T) ++void *av_buffer_pool_opaque(AVBufferRef *ref) { ++ BufferPoolEntry *buf = av_buffer_get_opaque(ref); ++ return buf->opaque; ++} +diff --git a/libavutil/buffer.h b/libavutil/buffer.h +index fab745f853..d0271e50fc 100644 +--- a/libavutil/buffer.h ++++ b/libavutil/buffer.h +@@ -289,6 +289,9 @@ void av_buffer_pool_uninit(AVBufferPool **pool); + */ + AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); + ++// Return the opaque for the underlying frame ++void *av_buffer_pool_opaque(AVBufferRef *ref); ++ + /** + * @} + */ +diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c +index 8ed52751c1..5e2b5ec3bc 100644 +--- a/libavutil/pixdesc.c ++++ b/libavutil/pixdesc.c +@@ -1989,6 +1989,18 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { + .name = "cuda", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, ++ [AV_PIX_FMT_RPI] = { ++ .name = "rpi", ++ .flags = AV_PIX_FMT_FLAG_HWACCEL, ++ }, ++ [AV_PIX_FMT_RPI4_10] = { ++ .name = "rpi", ++ .flags = AV_PIX_FMT_FLAG_HWACCEL, ++ }, ++ [AV_PIX_FMT_RPI4_8] = { ++ .name = "rpi", ++ .flags = AV_PIX_FMT_FLAG_HWACCEL, ++ }, + [AV_PIX_FMT_AYUV64LE] = { + .name = "ayuv64le", + .nb_components = 4, +diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h +index 34a1531489..0a6ff1f482 100644 +--- a/libavutil/pixfmt.h ++++ b/libavutil/pixfmt.h +@@ -234,6 +234,11 @@ enum AVPixelFormat { + */ + AV_PIX_FMT_CUDA, + ++ /** ++ * HW acceleration through RPI. ++ */ ++ AV_PIX_FMT_RPI, ++ + AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined + AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined + AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined +@@ -334,6 +339,14 @@ enum AVPixelFormat { + */ + AV_PIX_FMT_OPENCL, + ++// RPI - not on ifdef so can be got at by calling progs ++ AV_PIX_FMT_SAND128, ///< 4:2:0 8-bit 128x*Y stripe, 64x*UV stripe, then next x stripe, mysterious padding ++ AV_PIX_FMT_SAND64_10, ///< 4:2:0 10-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding ++ AV_PIX_FMT_SAND64_16, ///< 4:2:0 16-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding ++ ++ AV_PIX_FMT_RPI4_8, ++ AV_PIX_FMT_RPI4_10, ++ + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions + }; + +diff --git a/pi-util/conf_pi1.sh b/pi-util/conf_pi1.sh +new file mode 100644 +index 0000000000..ec25b81c31 +--- /dev/null ++++ b/pi-util/conf_pi1.sh +@@ -0,0 +1,31 @@ ++echo "Configure for Pi1" ++ ++RPI_TOOLROOT=`pwd`/../tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf ++RPI_OPT_VC=`pwd`/../firmware/opt/vc ++ ++RPI_INCLUDES="-I$RPI_OPT_VC/include -I$RPI_OPT_VC/include/interface/vcos/pthreads -I$RPI_OPT_VC/include/interface/vmcs_host/linux" ++RPI_DEFS="-D__VCCOREVER__=0x04000000 -DRPI=1" ++RPI_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib" ++#RPI_KEEPS="-save-temps=obj" ++RPI_KEEPS="" ++ ++./configure --enable-cross-compile\ ++ --cpu=arm1176jzf-s\ ++ --arch=arm\ ++ --disable-neon\ ++ --target-os=linux\ ++ --disable-stripping\ ++ --enable-mmal\ ++ --extra-cflags="-g $RPI_KEEPS $RPI_DEFS $RPI_INCLUDES"\ ++ --extra-cxxflags="$RPI_DEFS $RPI_INCLUDES"\ ++ --extra-ldflags="$RPI_LIBDIRS -Wl,-rpath=/opt/vc/lib,-rpath-link=$RPI_OPT_VC/lib,-rpath=/lib,-rpath=/usr/lib,-rpath-link=$RPI_TOOLROOT/lib,-rpath-link=$RPI_TOOLROOT/lib"\ ++ --extra-libs="-Wl,--start-group -lbcm_host -lmmal -lmmal_util -lmmal_core -lvcos -lvcsm -lvchostif -lvchiq_arm"\ ++ --cross-prefix=$RPI_TOOLROOT/bin/arm-linux-gnueabihf- ++ ++ ++# --enable-extra-warnings\ ++# --arch=armv71\ ++# --enable-shared\ ++ ++# gcc option for getting asm listing ++# -Wa,-ahls +diff --git a/pi-util/conf_pi2.sh b/pi-util/conf_pi2.sh +new file mode 100644 +index 0000000000..7ec0402ce8 +--- /dev/null ++++ b/pi-util/conf_pi2.sh +@@ -0,0 +1,34 @@ ++echo "Configure for Pi2/3" ++ ++RPI_TOOLROOT=/home/dom/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf ++RPI_OPT_VC=/opt/bcm-rootfs/opt/vc ++ ++RPI_INCLUDES="-I$RPI_OPT_VC/include -I$RPI_OPT_VC/include/interface/vcos/pthreads -I$RPI_OPT_VC/include/interface/vmcs_host/linux" ++RPI_DEFS="-D__VCCOREVER__=0x04000000 -DRPI_DISPLAY=1" ++RPI_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib" ++#RPI_KEEPS="-save-temps=obj" ++RPI_KEEPS="" ++ ++./configure --enable-cross-compile\ ++ --arch=armv6t2\ ++ --cpu=cortex-a7\ ++ --target-os=linux\ ++ --disable-stripping\ ++ --disable-thumb\ ++ --enable-mmal\ ++ --enable-rpi\ ++ --extra-cflags="-g $RPI_KEEPS $RPI_DEFS $RPI_INCLUDES"\ ++ --extra-cxxflags="$RPI_DEFS $RPI_INCLUDES"\ ++ --extra-ldflags="$RPI_LIBDIRS -Wl,-rpath=/opt/vc/lib,-rpath-link=$RPI_OPT_VC/lib,-rpath=/lib,-rpath=/usr/lib,-rpath-link=$RPI_TOOLROOT/lib,-rpath-link=$RPI_TOOLROOT/lib"\ ++ --extra-libs="-Wl,--start-group -lbcm_host -lmmal -lmmal_util -lmmal_core -lvcos -lvcsm -lvchostif -lvchiq_arm"\ ++ --cross-prefix=$RPI_TOOLROOT/bin/arm-linux-gnueabihf- \ ++ --prefix=$HOME/buster/home/pi/projects/fpga \ ++ --extra-libs="-ldl" ++ ++# --disable-decoders --enable-decoder=hevc --disable-hwaccels --enable-hwaccel=hevc_rpi --disable-encoders --enable-encoder=rawvideo --enable-muxer=rawvideo \ ++# --enable-extra-warnings\ ++# --arch=armv71\ ++# --enable-shared\ ++ ++# gcc option for getting asm listing ++# -Wa,-ahls diff --git a/projects/RPi/devices/RPi4/patches/kodi/kodi-001-hack-in-mmal.patch b/projects/RPi/devices/RPi4/patches/kodi/kodi-001-hack-in-mmal.patch new file mode 100644 index 0000000000..c46c5cdd47 --- /dev/null +++ b/projects/RPi/devices/RPi4/patches/kodi/kodi-001-hack-in-mmal.patch @@ -0,0 +1,5273 @@ +From a67cb967b02cfb59c448d3c6a5a2bc1ecfe933a6 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 24 Apr 2019 17:01:32 +0100 +Subject: [PATCH 01/14] hack: Nobble gles3 detection + +--- + cmake/modules/FindOpenGLES.cmake | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cmake/modules/FindOpenGLES.cmake b/cmake/modules/FindOpenGLES.cmake +index 0191d9e78c..c85a17928a 100644 +--- a/cmake/modules/FindOpenGLES.cmake ++++ b/cmake/modules/FindOpenGLES.cmake +@@ -42,7 +42,7 @@ find_path(OPENGLES3_INCLUDE_DIR GLES3/gl3.h + + if(OPENGLES_FOUND) + set(OPENGLES_LIBRARIES ${OPENGLES_gl_LIBRARY}) +- if(OPENGLES3_INCLUDE_DIR) ++ if(OPENGLES3x_INCLUDE_DIR) + set(OPENGLES_INCLUDE_DIRS ${OPENGLES_INCLUDE_DIR} ${OPENGLES3_INCLUDE_DIR}) + set(OPENGLES_DEFINITIONS -DHAS_GLES=3) + mark_as_advanced(OPENGLES_INCLUDE_DIR OPENGLES3_INCLUDE_DIR OPENGLES_gl_LIBRARY) +-- +2.20.1 + + +From 3cb1b595f36b6f6ba8befad52912ab245b91c0ab Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 4 Jun 2019 13:38:44 +0100 +Subject: [PATCH 02/14] ffmpeg: hevc: Add gpu based hevc optimisation + +--- + tools/depends/target/ffmpeg/Makefile | 6 +- + .../ffmpeg/pfcd_hevc_optimisations.patch | 4102 +++++++++++++++++ + 2 files changed, 4107 insertions(+), 1 deletion(-) + create mode 100644 tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch + +diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile +index 47acb73bdd..0bb9eb375e 100644 +--- a/tools/depends/target/ffmpeg/Makefile ++++ b/tools/depends/target/ffmpeg/Makefile +@@ -1,6 +1,7 @@ + include ../../Makefile.include + include FFMPEG-VERSION +-DEPS= ../../Makefile.include FFMPEG-VERSION Makefile ++DEPS= ../../Makefile.include FFMPEG-VERSION Makefile \ ++ pfcd_hevc_optimisations.patch \ + + # set to "yes" to enable patching + # we don't apply patches until we move to a vanilla ffmpeg tarball +@@ -68,6 +69,8 @@ ifeq ($(Configuration), Release) + ffmpg_config += --disable-debug + endif + ++ffmpg_config += --enable-rpi ++ + all: .installed-$(PLATFORM) + + $(TARBALLS_LOCATION)/$(ARCHIVE): +@@ -77,6 +80,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) + rm -rf $(PLATFORM); mkdir -p $(PLATFORM) + cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + cd $(PLATFORM); sed -i".bak" -e "s%pkg_config_default=pkg-config%export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig \&\& pkg_config_default=$(NATIVEPREFIX)/bin/pkg-config%" configure ++ cd $(PLATFORM); patch -p1 < ../pfcd_hevc_optimisations.patch + cd $(PLATFORM);\ + CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ + ./configure $(ffmpg_config) +diff --git a/tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch b/tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch +new file mode 100644 +index 0000000000..fbdc27f516 +--- /dev/null ++++ b/tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch +@@ -0,0 +1,4102 @@ ++diff --git a/configure b/configure ++index 172611bb4a..fa204fca71 100755 ++--- a/configure +++++ b/configure ++@@ -1782,6 +1782,8 @@ HWACCEL_LIBRARY_LIST=" ++ mmal ++ omx ++ opencl +++ rpi4_8 +++ rpi4_10 ++ " ++ ++ DOCUMENT_LIST=" ++@@ -1843,6 +1845,7 @@ SUBSYSTEM_LIST=" ++ pixelutils ++ network ++ rdft +++ rpi ++ " ++ ++ # COMPONENT_LIST needs to come last to ensure correct dependency checking ++@@ -2312,6 +2315,7 @@ CONFIG_EXTRA=" ++ rangecoder ++ riffdec ++ riffenc +++ rpi ++ rtpdec ++ rtpenc_chain ++ rv34dsp ++diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c ++index c0214c42d8..3f43b58cbb 100644 ++--- a/fftools/ffmpeg.c +++++ b/fftools/ffmpeg.c ++@@ -23,6 +23,11 @@ ++ * multimedia converter based on the FFmpeg libraries ++ */ ++ +++#ifdef RPI +++//#define RPI_DISPLAY +++#define RPI_DISPLAY_ALL 0 +++#endif +++ ++ #include "config.h" ++ #include ++ #include ++@@ -70,6 +75,24 @@ ++ # include "libavfilter/buffersrc.h" ++ # include "libavfilter/buffersink.h" ++ +++#ifdef RPI_DISPLAY +++#pragma GCC diagnostic push +++// Many many redundant decls in the header files +++#pragma GCC diagnostic ignored "-Wredundant-decls" +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#pragma GCC diagnostic pop +++#include "libavcodec/rpi_qpu.h" +++#include "libavcodec/rpi_zc.h" +++#endif +++ ++ #if HAVE_SYS_RESOURCE_H ++ #include ++ #include ++@@ -162,6 +185,247 @@ static int restore_tty; ++ static void free_input_threads(void); ++ #endif ++ +++#ifdef RPI_DISPLAY +++ +++#define NUM_BUFFERS 4 +++ +++ +++typedef struct rpi_display_env_s +++{ +++ MMAL_COMPONENT_T* display; +++ MMAL_COMPONENT_T* isp; +++ MMAL_PORT_T * port_in; // Input port of either isp or display depending on pipe setup +++ MMAL_CONNECTION_T * conn; +++ +++ MMAL_POOL_T *rpi_pool; +++ volatile int rpi_display_count; +++ enum AVPixelFormat avfmt; +++} rpi_display_env_t; +++ +++static rpi_display_env_t * rpi_display_env = NULL; +++ +++ +++static MMAL_POOL_T* display_alloc_pool(MMAL_PORT_T* port) +++{ +++ MMAL_POOL_T* pool; +++ mmal_port_parameter_set_boolean(port, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); // Does this mark that the buffer contains a vc_handle? Would have expected a vc_image? +++ pool = mmal_port_pool_create(port, NUM_BUFFERS, 0); +++ assert(pool); +++ +++ return pool; +++} +++ +++static void display_cb_input(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { +++ rpi_display_env_t *const de = (rpi_display_env_t *)port->userdata; +++ av_rpi_zc_unref(buffer->user_data); +++ atomic_fetch_add(&de->rpi_display_count, -1); +++ mmal_buffer_header_release(buffer); +++} +++ +++static void display_cb_control(MMAL_PORT_T *port,MMAL_BUFFER_HEADER_T *buffer) { +++ mmal_buffer_header_release(buffer); +++} +++ +++#define DISPLAY_PORT_DEPTH 4 +++ +++static rpi_display_env_t * +++display_init(const enum AVPixelFormat req_fmt, size_t x, size_t y, size_t w, size_t h) +++{ +++ MMAL_STATUS_T err; +++ MMAL_DISPLAYREGION_T region = +++ { +++ .hdr = {MMAL_PARAMETER_DISPLAYREGION, sizeof(region)}, +++ .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_FULLSCREEN | MMAL_DISPLAY_SET_DEST_RECT, +++ .layer = 2, +++ .fullscreen = 0, +++ .dest_rect = {x, y, w, h} +++ }; +++#if RPI_ZC_SAND_8_IN_10_BUF +++ const enum AVPixelFormat fmt = (req_fmt == AV_PIX_FMT_YUV420P10 || av_rpi_is_sand_format(req_fmt)) ? AV_PIX_FMT_SAND128 : req_fmt; +++#else +++ const enum AVPixelFormat fmt = (req_fmt == AV_PIX_FMT_YUV420P10) ? AV_PIX_FMT_SAND128 : req_fmt; +++#endif +++ const AVRpiZcFrameGeometry geo = av_rpi_zc_frame_geometry(fmt, w, h); +++ rpi_display_env_t * de; +++ int isp_req = (fmt == AV_PIX_FMT_SAND64_10); +++ +++ bcm_host_init(); // Needs to be done by someone... +++ +++ if ((de = av_mallocz(sizeof(*de))) == NULL) { +++ return NULL; +++ } +++ +++ mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &de->display); +++ av_assert0(de->display); +++ de->port_in = de->display->input[0]; +++ +++ if (isp_req) +++ { +++ mmal_component_create("vc.ril.isp", &de->isp); +++ de->port_in = de->isp->input[0]; +++ } +++ +++ mmal_port_parameter_set(de->display->input[0], ®ion.hdr); +++ +++ { +++ MMAL_PORT_T * const port = de->port_in; +++ MMAL_ES_FORMAT_T* const format = port->format; +++ port->userdata = (struct MMAL_PORT_USERDATA_T *)de; +++ port->buffer_num = DISPLAY_PORT_DEPTH; +++ format->encoding = +++ fmt == AV_PIX_FMT_SAND128 ? MMAL_ENCODING_YUVUV128 : +++ fmt == AV_PIX_FMT_RPI4_8 ? MMAL_ENCODING_YUVUV128 : +++ fmt == AV_PIX_FMT_RPI4_10 ? MMAL_ENCODING_YUV10_COL : +++ fmt == AV_PIX_FMT_SAND64_10 ? MMAL_ENCODING_YUVUV64_16 : +++ MMAL_ENCODING_I420; +++ format->es->video.width = geo.stride_y; +++ format->es->video.height = (fmt == AV_PIX_FMT_SAND128 || +++ fmt == AV_PIX_FMT_RPI4_8 || +++ fmt == AV_PIX_FMT_RPI4_10 || +++ fmt == AV_PIX_FMT_SAND64_10) ? +++ (h + 15) & ~15 : geo.height_y; // Magic +++ format->es->video.crop.x = 0; +++ format->es->video.crop.y = 0; +++ format->es->video.crop.width = w; +++ format->es->video.crop.height = h; +++ mmal_port_format_commit(port); +++ } +++ +++ de->rpi_pool = display_alloc_pool(de->port_in); +++ mmal_port_enable(de->port_in,display_cb_input); +++ +++ if (isp_req) { +++ MMAL_PORT_T * const port_out = de->isp->output[0]; +++ mmal_log_dump_port(de->port_in); +++ mmal_format_copy(port_out->format, de->port_in->format); +++ if (fmt == AV_PIX_FMT_SAND64_10) { +++ if ((err = mmal_port_parameter_set_int32(de->port_in, MMAL_PARAMETER_CCM_SHIFT, 5)) != MMAL_SUCCESS || +++ (err = mmal_port_parameter_set_int32(port_out, MMAL_PARAMETER_OUTPUT_SHIFT, 1)) != MMAL_SUCCESS) +++ { +++ av_log(NULL, AV_LOG_WARNING, "Failed to set ISP output port shift\n"); +++ } +++ else +++ av_log(NULL, AV_LOG_WARNING, "Set ISP output port shift OK\n"); +++ +++ } +++ port_out->format->encoding = MMAL_ENCODING_I420; +++ mmal_log_dump_port(port_out); +++ if ((err = mmal_port_format_commit(port_out)) != MMAL_SUCCESS) +++ { +++ av_log(NULL, AV_LOG_ERROR, "Failed to set ISP output port format\n"); +++ goto fail; +++ } +++ if ((err = mmal_connection_create(&de->conn, port_out, de->display->input[0], MMAL_CONNECTION_FLAG_TUNNELLING)) != MMAL_SUCCESS) { +++ av_log(NULL, AV_LOG_ERROR, "Failed to create connection\n"); +++ goto fail; +++ } +++ if ((err = mmal_connection_enable(de->conn)) != MMAL_SUCCESS) { +++ av_log(NULL, AV_LOG_ERROR, "Failed to enable connection\n"); +++ goto fail; +++ } +++ mmal_port_enable(de->isp->control,display_cb_control); +++ mmal_component_enable(de->isp); +++ } +++ +++ mmal_component_enable(de->display); +++ mmal_port_enable(de->display->control,display_cb_control); +++ de->avfmt = fmt; +++ +++ printf("Allocated display %dx%d in %dx%d, fmt=%d\n", w, h, geo.stride_y, geo.height_y, fmt); +++ +++ return de; +++ +++fail: +++ // **** Free stuff +++ return NULL; +++} +++ +++static void display_frame(struct AVCodecContext * const s, rpi_display_env_t * const de, const AVFrame* const fr) +++{ +++ MMAL_BUFFER_HEADER_T* buf; +++ +++ if (de == NULL) +++ return; +++ +++ if (atomic_load(&de->rpi_display_count) >= DISPLAY_PORT_DEPTH - 1) { +++ av_log(s, AV_LOG_VERBOSE, "Frame dropped\n"); +++ return; +++ } +++ +++ buf = mmal_queue_get(de->rpi_pool->queue); +++ if (!buf) { +++ // Running too fast so drop the frame +++ printf("Q alloc failure\n"); +++ return; +++ } +++ assert(buf); +++ buf->cmd = 0; +++ buf->offset = 0; // Offset to valid data +++ buf->flags = 0; +++ { +++ const AVRpiZcRefPtr fr_buf = av_rpi_zc_ref(s, fr, de->avfmt, 1); +++ if (fr_buf == NULL) { +++ mmal_buffer_header_release(buf); +++ return; +++ } +++ +++ buf->user_data = fr_buf; +++ buf->data = (uint8_t *)av_rpi_zc_vc_handle(fr_buf); // Cast our handle to a pointer for mmal +++ buf->offset = av_rpi_zc_offset(fr_buf); +++ buf->length = av_rpi_zc_length(fr_buf); +++ buf->alloc_size = av_rpi_zc_numbytes(fr_buf); +++ atomic_fetch_add(&de->rpi_display_count, 1); +++ } +++#if RPI_DISPLAY_ALL +++ while (atomic_load(&de->rpi_display_count) >= DISPLAY_PORT_DEPTH - 1) { +++ usleep(5000); +++ } +++#endif +++ +++ if (mmal_port_send_buffer(de->port_in, buf) != MMAL_SUCCESS) +++ { +++ av_log(s, AV_LOG_ERROR, "mmal_port_send_buffer failed: depth=%d\n", de->rpi_display_count); +++ display_cb_input(de->port_in, buf); +++ } +++} +++ +++static void display_exit(rpi_display_env_t ** const pde) +++{ +++ rpi_display_env_t * const de = *pde; +++ *pde = NULL; +++ +++ if (de != NULL) { +++// sleep(120); +++ +++ if (de->port_in != NULL) { +++ mmal_port_disable(de->port_in); +++ } +++ +++ // The above disable should kick out all buffers - check that +++ if (atomic_load(&de->rpi_display_count) != 0) { +++ av_log(NULL, AV_LOG_WARNING, "Exiting with display count non-zero:%d\n", atomic_load(&de->rpi_display_count)); +++ } +++ +++ if (de->conn != NULL) { +++ mmal_connection_destroy(de->conn); +++ } +++ if (de->isp != NULL) { +++ mmal_component_destroy(de->isp); +++ } +++ if (de->display != NULL) { +++ mmal_component_destroy(de->display); +++ } +++ if (de->rpi_pool != NULL) { +++ mmal_port_pool_destroy(de->display->input[0], de->rpi_pool); +++ } +++ +++ av_free(de); +++ } +++} +++ +++#endif +++ +++ ++ /* sub2video hack: ++ Convert subtitles to video with alpha to insert them in filter graphs. ++ This is a temporary solution until libavfilter gets real subtitles support. ++@@ -583,6 +847,11 @@ static void ffmpeg_cleanup(int ret) ++ avformat_close_input(&input_files[i]->ctx); ++ av_freep(&input_files[i]); ++ } +++ +++#ifdef RPI_DISPLAY +++ display_exit(&rpi_display_env); +++#endif +++ ++ for (i = 0; i < nb_input_streams; i++) { ++ InputStream *ist = input_streams[i]; ++ ++@@ -594,7 +863,9 @@ static void ffmpeg_cleanup(int ret) ++ av_freep(&ist->filters); ++ av_freep(&ist->hwaccel_device); ++ av_freep(&ist->dts_buffer); ++- +++#ifdef RPI_DISPLAY +++ av_rpi_zc_uninit(ist->dec_ctx); +++#endif ++ avcodec_free_context(&ist->dec_ctx); ++ ++ av_freep(&input_streams[i]); ++@@ -625,6 +896,7 @@ static void ffmpeg_cleanup(int ret) ++ } ++ term_exit(); ++ ffmpeg_exited = 1; +++ ++ } ++ ++ void remove_avoptions(AVDictionary **a, AVDictionary *b) ++@@ -1060,6 +1332,15 @@ static void do_video_out(OutputFile *of, ++ if (ost->source_index >= 0) ++ ist = input_streams[ost->source_index]; ++ +++#ifdef RPI_DISPLAY +++ if (next_picture && ist != NULL) +++ { +++ if (rpi_display_env == NULL) +++ rpi_display_env = display_init(next_picture->format, 0, 0, next_picture->width, next_picture->height); +++ display_frame(ist->dec_ctx, rpi_display_env, next_picture); +++ } +++#endif +++ ++ frame_rate = av_buffersink_get_frame_rate(filter); ++ if (frame_rate.num > 0 && frame_rate.den > 0) ++ duration = 1/(av_q2d(frame_rate) * av_q2d(enc->time_base)); ++@@ -1275,7 +1556,7 @@ static void do_video_out(OutputFile *of, ++ ++ ost->frames_encoded++; ++ ++- ret = avcodec_send_frame(enc, in_picture); +++ ret = 0;//avcodec_send_frame(enc, in_picture); ++ if (ret < 0) ++ goto error; ++ ++@@ -2891,6 +3172,12 @@ static int init_input_stream(int ist_index, char *error, int error_len) ++ ist->dec_ctx->opaque = ist; ++ ist->dec_ctx->get_format = get_format; ++ ist->dec_ctx->get_buffer2 = get_buffer; +++ +++#ifdef RPI_DISPLAY +++ // Overrides the above get_buffer2 +++ av_rpi_zc_init(ist->dec_ctx); +++#endif +++ ++ ist->dec_ctx->thread_safe_callbacks = 1; ++ ++ av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); ++diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h ++index d44b7a5c72..0c5fa38f1d 100644 ++--- a/fftools/ffmpeg.h +++++ b/fftools/ffmpeg.h ++@@ -62,6 +62,7 @@ enum HWAccelID { ++ HWACCEL_VIDEOTOOLBOX, ++ HWACCEL_QSV, ++ HWACCEL_CUVID, +++ HWACCEL_RPI, ++ }; ++ ++ typedef struct HWAccel { ++@@ -654,6 +655,7 @@ int ffmpeg_parse_options(int argc, char **argv); ++ int videotoolbox_init(AVCodecContext *s); ++ int qsv_init(AVCodecContext *s); ++ int cuvid_init(AVCodecContext *s); +++int rpi_init(AVCodecContext *s); ++ ++ HWDevice *hw_device_get_by_name(const char *name); ++ int hw_device_init_from_string(const char *arg, HWDevice **dev); ++diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c ++index d7a7eb0662..4ee87e742b 100644 ++--- a/fftools/ffmpeg_opt.c +++++ b/fftools/ffmpeg_opt.c ++@@ -74,6 +74,10 @@ const HWAccel hwaccels[] = { ++ #endif ++ #if CONFIG_CUVID ++ { "cuvid", cuvid_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA }, +++#endif +++#if CONFIG_RPI +++ { "rpi", rpi_init, HWACCEL_RPI, AV_PIX_FMT_RPI4_8 }, +++ { "rpi", rpi_init, HWACCEL_RPI, AV_PIX_FMT_RPI4_10 }, ++ #endif ++ { 0 }, ++ }; ++diff --git a/libavcodec/Makefile b/libavcodec/Makefile ++index 4b8ad121db..40ec4691ef 100644 ++--- a/libavcodec/Makefile +++++ b/libavcodec/Makefile ++@@ -6,6 +6,10 @@ HEADERS = ac3_parser.h \ ++ avcodec.h \ ++ avdct.h \ ++ avfft.h \ +++ rpi_qpu.h \ +++ rpi_mailbox.h \ +++ rpi_zc.h \ +++ rpi_ctrl_ffmpeg.h \ ++ d3d11va.h \ ++ dirac.h \ ++ dv_profile.h \ ++@@ -48,6 +52,10 @@ OBJS = ac3_parser.o \ ++ qsv_api.o \ ++ raw.o \ ++ utils.o \ +++ rpi_qpu.o \ +++ rpi_mailbox.o \ +++ rpi_zc.o \ +++ rpi_ctrl_ffmpeg.o \ ++ vorbis_parser.o \ ++ xiph.o \ ++ ++@@ -360,6 +368,7 @@ OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o ++ OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \ ++ hevc_cabac.o hevc_refs.o hevcpred.o \ ++ hevcdsp.o hevc_filter.o hevc_data.o +++OBJS-$(CONFIG_RPI) += rpi_hevc.o ++ OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o ++ OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o ++ OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o ++diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h ++index fb0c6fae70..798d0903eb 100644 ++--- a/libavcodec/avcodec.h +++++ b/libavcodec/avcodec.h ++@@ -3208,7 +3208,13 @@ typedef struct AVCodecContext { ++ #endif ++ ++ /** ++- * Audio only. The amount of padding (in samples) appended by the encoder to +++ * Opaque pointer for use by replacement get_buffer2 code +++ * +++ * @author jc (08/02/2016) +++ */ +++ void * get_buffer_context; +++ +++ /* Audio only. The amount of padding (in samples) appended by the encoder to ++ * the end of the audio. I.e. this number of decoded samples must be ++ * discarded by the caller from the end of the stream to get the original ++ * audio without any trailing padding. ++diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c ++index c8877626d2..da769116ec 100644 ++--- a/libavcodec/hevcdec.c +++++ b/libavcodec/hevcdec.c ++@@ -364,12 +364,17 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) ++ CONFIG_HEVC_NVDEC_HWACCEL + \ ++ CONFIG_HEVC_VAAPI_HWACCEL + \ ++ CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + \ +++ CONFIG_HEVC_RPI4_8_HWACCEL + \ +++ CONFIG_HEVC_RPI4_10_HWACCEL + \ ++ CONFIG_HEVC_VDPAU_HWACCEL) ++ enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; ++ ++ switch (sps->pix_fmt) { ++ case AV_PIX_FMT_YUV420P: ++ case AV_PIX_FMT_YUVJ420P: +++#if CONFIG_HEVC_RPI4_8_HWACCEL +++ *fmt++ = AV_PIX_FMT_RPI4_8; +++#endif ++ #if CONFIG_HEVC_DXVA2_HWACCEL ++ *fmt++ = AV_PIX_FMT_DXVA2_VLD; ++ #endif ++@@ -391,6 +396,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) ++ #endif ++ break; ++ case AV_PIX_FMT_YUV420P10: +++#if CONFIG_HEVC_RPI4_10_HWACCEL +++ *fmt++ = AV_PIX_FMT_RPI4_10; +++#endif ++ #if CONFIG_HEVC_DXVA2_HWACCEL ++ *fmt++ = AV_PIX_FMT_DXVA2_VLD; ++ #endif ++@@ -3556,6 +3564,12 @@ AVCodec ff_hevc_decoder = { ++ #endif ++ #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL ++ HWACCEL_VIDEOTOOLBOX(hevc), +++#endif +++#if CONFIG_HEVC_RPI4_8_HWACCEL +++ HWACCEL_RPI4_8(hevc), +++#endif +++#if CONFIG_HEVC_RPI4_10_HWACCEL +++ HWACCEL_RPI4_10(hevc), ++ #endif ++ NULL ++ }, ++diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h ++index 3aaa92571c..c6bc36b3e3 100644 ++--- a/libavcodec/hwaccel.h +++++ b/libavcodec/hwaccel.h ++@@ -80,5 +80,9 @@ typedef struct AVCodecHWConfigInternal { ++ HW_CONFIG_HWACCEL(0, 0, 1, D3D11VA_VLD, NONE, ff_ ## codec ## _d3d11va_hwaccel) ++ #define HWACCEL_XVMC(codec) \ ++ HW_CONFIG_HWACCEL(0, 0, 1, XVMC, NONE, ff_ ## codec ## _xvmc_hwaccel) +++#define HWACCEL_RPI4_8(codec) \ +++ HW_CONFIG_HWACCEL(0, 0, 1, RPI4_8, NONE, ff_ ## codec ## _rpi4_8_hwaccel) +++#define HWACCEL_RPI4_10(codec) \ +++ HW_CONFIG_HWACCEL(0, 0, 1, RPI4_10, NONE, ff_ ## codec ## _rpi4_10_hwaccel) ++ ++ #endif /* AVCODEC_HWACCEL_H */ ++diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h ++index 7d73da8676..01799f869a 100644 ++--- a/libavcodec/hwaccels.h +++++ b/libavcodec/hwaccels.h ++@@ -74,5 +74,7 @@ extern const AVHWAccel ff_wmv3_dxva2_hwaccel; ++ extern const AVHWAccel ff_wmv3_nvdec_hwaccel; ++ extern const AVHWAccel ff_wmv3_vaapi_hwaccel; ++ extern const AVHWAccel ff_wmv3_vdpau_hwaccel; +++extern const AVHWAccel ff_hevc_rpi4_8_hwaccel; +++extern const AVHWAccel ff_hevc_rpi4_10_hwaccel; ++ ++ #endif /* AVCODEC_HWACCELS_H */ ++diff --git a/libavcodec/rpi_ctrl_ffmpeg.c b/libavcodec/rpi_ctrl_ffmpeg.c ++new file mode 100644 ++index 0000000000..6d93adba03 ++--- /dev/null +++++ b/libavcodec/rpi_ctrl_ffmpeg.c ++@@ -0,0 +1,427 @@ +++#include +++#include +++#include +++#include +++ +++// How to access GPIO registers from C-code on the Raspberry-Pi +++// Example program +++// 15-January-2012 +++// Dom and Gert +++ +++// Access from ARM Running Linux +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#include +++#include +++#include +++#include +++#include "rpi_mailbox.h" +++#include "rpi_ctrl_ffmpeg.h" +++ +++#define av_assert0(x) assert(x) +++ +++// argon block doesn't see VC sdram alias bits +++#define MANGLE(x) ((x) &~0xc0000000) +++#ifdef AXI_BUFFERS +++#define AXI_MEM_SIZE (64*1024*1024) +++#else +++#define AXI_MEM_SIZE (64*1024*1024) +++#endif +++ +++#define PAGE_SIZE (4*1024) +++#define BLOCK_SIZE (0x10000) +++#define CACHED 0 +++#define VERBOSE 0 +++ +++static inline void __DMB2(void) {}//{ asm volatile ("dmb" ::: "memory"); } +++ +++ +++// GPU memory alloc fns (internal) +++typedef struct gpu_mem_ptr_s { +++ unsigned char *arm; // Pointer to memory mapped on ARM side +++ int vc_handle; // Videocore handle of relocatable memory +++ int vcsm_handle; // Handle for use by VCSM +++ unsigned int vc; // Address for use in GPU code +++ unsigned int numbytes; // Size of memory block +++} GPU_MEM_PTR_T; +++ +++typedef enum +++{ +++ RPI_CACHE_FLUSH_MODE_INVALIDATE = 1, +++ RPI_CACHE_FLUSH_MODE_WRITEBACK = 2, +++ RPI_CACHE_FLUSH_MODE_WB_INVALIDATE = 3 +++} rpi_cache_flush_mode_t; +++ +++// GPU_MEM_PTR_T alloc fns +++static int gpu_malloc_cached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { +++ p->numbytes = (numbytes + 255) & ~255; // Round up +++ p->vcsm_handle = vcsm_malloc_cache(p->numbytes, VCSM_CACHE_TYPE_HOST | 0x80, (char *)"Video Frame" ); +++ av_assert0(p->vcsm_handle); +++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); +++ av_assert0(p->vc_handle); +++ p->arm = vcsm_lock(p->vcsm_handle); +++ av_assert0(p->arm); +++ p->vc = mbox_mem_lock(mb, p->vc_handle); +++ av_assert0(p->vc); +++ printf("***** %s, %d\n", __func__, numbytes); +++ +++ return 0; +++} +++ +++static int gpu_malloc_uncached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { +++ p->numbytes = numbytes; +++ p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE | 0x80, (char *)"Video Frame" ); +++ av_assert0(p->vcsm_handle); +++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); +++ av_assert0(p->vc_handle); +++ p->arm = vcsm_lock(p->vcsm_handle); +++ av_assert0(p->arm); +++ p->vc = mbox_mem_lock(mb, p->vc_handle); +++ av_assert0(p->vc); +++ printf("***** %s, %d\n", __func__, numbytes); +++ return 0; +++} +++ +++static void gpu_free_internal(const int mb, GPU_MEM_PTR_T * const p) { +++ mbox_mem_unlock(mb, p->vc_handle); +++ vcsm_unlock_ptr(p->arm); +++ vcsm_free(p->vcsm_handle); +++ memset(p, 0, sizeof(*p)); // Ensure we crash hard if we try and use this again +++ printf("***** %s\n", __func__); +++} +++ +++static void gpu_clean_invalidate(GPU_MEM_PTR_T * const p, int mode) { +++ struct vcsm_user_clean_invalid_s iocache = {}; +++ iocache.s[0].handle = p->vcsm_handle; +++ iocache.s[0].cmd = mode; +++ iocache.s[0].addr = (int) p->arm; +++ iocache.s[0].size = p->numbytes; +++ vcsm_clean_invalid( &iocache ); +++ printf("***** %s mode:%d\n", __func__, mode); +++} +++ +++// +++// Set up a memory regions to access periperhals +++// +++static void *setup_io(const char *dev, unsigned long base) +++{ +++ void *gpio_map; +++ int mem_fd; +++ +++ /* open /dev/mem */ +++ if ((mem_fd = open(dev, O_RDWR|O_SYNC) ) < 0) { +++ printf("can't open %s\n", dev); +++ exit (-1); +++ } +++ // Now map it +++ gpio_map = (unsigned char *)mmap( +++ NULL, +++ BLOCK_SIZE, +++ PROT_READ|PROT_WRITE, +++ MAP_SHARED, +++ mem_fd, +++ base +++ ); +++ printf("%s: %08lx -> %p (fd:%d)\n", __FUNCTION__, base, gpio_map, mem_fd); +++ +++ if (gpio_map == MAP_FAILED) { +++ printf("mmap error %p\n", gpio_map); +++ //exit (-1); +++ } +++ +++ return gpio_map; +++} // setup_io +++ +++static void release_io(void *gpio_map) +++{ +++ int s = munmap(gpio_map, BLOCK_SIZE); +++ assert(s == 0); +++} +++ +++struct RPI_DEBUG { +++ FILE *fp_reg; +++ FILE *fp_bin; +++ int mbox; +++ GPU_MEM_PTR_T axi; +++ void *read_buf; +++ int32_t read_buf_size, read_buf_used; +++ volatile unsigned int *apb; +++ volatile unsigned int *interrupt; +++ //volatile unsigned int *sdram; +++}; +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++void rpi_apb_write_addr(void *id, uint16_t addr, uint32_t data) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "P %x %08x\n", addr, data); +++ __DMB2(); +++ rpi->apb[addr>>2] = data + (MANGLE(rpi->axi.vc)>>6); +++} +++ +++uint64_t rpi_axi_get_addr(void *id) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ return (uint64_t)MANGLE(rpi->axi.vc); +++} +++ +++void rpi_apb_write(void *id, uint16_t addr, uint32_t data) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "W %x %08x\n", addr, data); +++ __DMB2(); +++ rpi->apb[addr>>2] = data; +++} +++ +++uint32_t rpi_apb_read(void *id, uint16_t addr) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ uint32_t v = rpi->apb[addr>>2]; +++ __DMB2(); +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "R %x (=%x)\n", addr, v); +++ return v; +++} +++ +++void rpi_apb_read_drop(void *id, uint16_t addr) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ uint32_t v = rpi->apb[addr>>2]; +++ __DMB2(); +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "R %x (=%x)\n", addr, v); +++} +++ +++void rpi_axi_write(void *id, uint64_t addr, uint32_t size, void *buf) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "L %08" PRIx64 " %08x\n", addr, size); +++ assert(addr + size <= AXI_MEM_SIZE); +++ __DMB2(); +++ memcpy(rpi->axi.arm + addr, buf, size); +++} +++ +++void rpi_axi_read_alloc(void *id, uint32_t size) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ assert(rpi->read_buf == NULL); +++ rpi->read_buf = malloc(size); +++ rpi->read_buf_size = size; +++ rpi->read_buf_used = 0; +++} +++ +++void rpi_axi_read_tx(void *id, uint64_t addr, uint32_t size) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ assert(rpi->read_buf_used + size <= rpi->read_buf_size); +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "S %08" PRIx64 " %08x\n", addr, size); +++ assert(addr + size <= AXI_MEM_SIZE); +++ __DMB2(); +++ memcpy((char *)rpi->read_buf + rpi->read_buf_used, rpi->axi.arm + addr, size); +++ rpi->read_buf_used += size; +++} +++ +++void rpi_axi_read_rx(void *id, uint32_t size, void *buf) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ assert(size == rpi->read_buf_used); +++ fprintf(rpi->fp_reg, "Z " PRIx64 " %08x\n", size); +++ memcpy(buf, rpi->read_buf, size); +++ free(rpi->read_buf); +++ rpi->read_buf = NULL; +++ rpi->read_buf_size = 0; +++ rpi->read_buf_used = 0; +++} +++ +++static int getthreadnum(unsigned pid) +++{ +++ static unsigned pids[8]; +++ int i; +++ for (i = 0; i < 8; i++) +++ { +++ if (pids[i] == 0) +++ pids[i] = pid; +++ if (pids[i] == pid) +++ return i; +++ } +++ return -1; +++} +++ +++#define _NOP() //do { __asm__ __volatile__ ("nop"); } while (0) +++ +++static void yield(void) +++{ +++ int i; +++ for (i=0; i<0; i++) +++ _NOP(); +++ usleep(1000); +++} +++ +++ +++void rpi_wait_interrupt(void *id, int phase) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ static struct timespec tfirst={0,0}; +++ static __thread struct timespec tstart={0,0}; +++ struct timespec tend={0,0}; +++ unsigned pid = (unsigned)pthread_self(); +++ clock_gettime(CLOCK_MONOTONIC, &tend); +++ if (tstart.tv_sec == 0 && tstart.tv_nsec == 0) +++ tstart = tend; +++ if (tfirst.tv_sec == 0 && tfirst.tv_nsec == 0) +++ { +++ /*printf("%s: Resetting sdram stats\n", __FUNCTION__); +++ rpi->sdram[0x30/4] = 0;*/ +++ tfirst = tend; +++ } +++ if (VERBOSE) +++ printf("%08llu: %s: IN thread:%u phase:%d time:%llu\n", ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tfirst.tv_sec * 1000000000ULL + tfirst.tv_nsec))/1000, +++ __FUNCTION__, getthreadnum(pid), phase, ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tstart.tv_sec * 1000000000ULL + tstart.tv_nsec))/1000); +++ /*enum {IDL=0x30/4, RTC=0x34/4, WTC=0x38/4, RDC=0x3c/4, WDC=0x40/4, RAC=0x44/4, CYC=0x48/4, CMD=0x4c/4, DAT=0x50/4, RDCMD=0x78/4, RDSUB=0x7c/4, WRCMD=0x80/4, WRSUB=0x84/4, MWRCMD=0x88/4, MWRSUB=0x8c/4,}; +++ printf("IDL:%u RTC:%u WTC:%u RDC:%u WDC:%u RAC:%u CYC:%u CMD:%u DAT:%u RDCMD:%u RDSUB:%u WRCMD:%u WRSUB:%u MWRCMD:%u MWRSUB:%u\n", +++ rpi->sdram[IDL], rpi->sdram[RTC], rpi->sdram[WTC], rpi->sdram[RDC], rpi->sdram[WDC], rpi->sdram[RAC], rpi->sdram[CYC], rpi->sdram[CMD], rpi->sdram[DAT], +++ rpi->sdram[RDCMD], rpi->sdram[RDSUB], rpi->sdram[WRCMD], rpi->sdram[WRSUB], rpi->sdram[MWRCMD], rpi->sdram[MWRSUB]); +++ rpi->sdram[0x30/4] = 0;*/ +++ +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "I %d\n", phase); +++ __DMB2(); +++#if 0 +++ assert(phase == 1 || phase == 2); +++ for (;;) { +++ if (phase==1 && rpi->apb[0x74>>2]==rpi->apb[0x70>>2]) break; +++ else if (phase==2 && (rpi->apb[0x8028/*STATUS2*/>>2]&1)==0) break; +++ } +++ fprintf(rpi->fp_reg, "I %d done\n", phase); +++#else +++ #define ARG_IC_ICTRL_ACTIVE1_INT_SET 0x00000001 +++ #define ARG_IC_ICTRL_ACTIVE1_EDGE_SET 0x00000002 +++ #define ARG_IC_ICTRL_ACTIVE1_EN_SET 0x00000004 +++ #define ARG_IC_ICTRL_ACTIVE1_STATUS_SET 0x00000008 +++ #define ARG_IC_ICTRL_ACTIVE2_INT_SET 0x00000010 +++ #define ARG_IC_ICTRL_ACTIVE2_EDGE_SET 0x00000020 +++ #define ARG_IC_ICTRL_ACTIVE2_EN_SET 0x00000040 +++ #define ARG_IC_ICTRL_ACTIVE2_STATUS_SET 0x00000080 +++ //if (rpi->interrupt[0] &~ (ARG_IC_ICTRL_ACTIVE1_INT_SET|ARG_IC_ICTRL_ACTIVE2_INT_SET|ARG_IC_ICTRL_ACTIVE1_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET|ARG_IC_ICTRL_ACTIVE1_STATUS_SET|ARG_IC_ICTRL_ACTIVE2_STATUS_SET)) +++ //fprintf(rpi->fp_reg, "I %d %x in\n", phase, rpi->interrupt[0]); +++ +++ if (phase == 1) { +++ while (!(rpi->interrupt[0] & ARG_IC_ICTRL_ACTIVE1_INT_SET)) +++ yield(); +++ rpi->interrupt[0] = rpi->interrupt[0] &~ ARG_IC_ICTRL_ACTIVE2_INT_SET; //ARG_IC_ICTRL_ACTIVE1_INT_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET; +++ } else if (phase == 2) { +++ while (!(rpi->interrupt[0] & ARG_IC_ICTRL_ACTIVE2_INT_SET)) +++ yield(); +++ rpi->interrupt[0] = rpi->interrupt[0] &~ ARG_IC_ICTRL_ACTIVE1_INT_SET; //ARG_IC_ICTRL_ACTIVE2_INT_SET|ARG_IC_ICTRL_ACTIVE1_EDGE_SET|ARG_IC_ICTRL_ACTIVE2_EDGE_SET; +++ } else assert(0); +++#endif +++ //fprintf(rpi->fp_reg, "I %d %x out\n", phase, rpi->interrupt[0]); +++ if (phase == 2) +++ { +++ __DMB2(); +++ if (VERBOSE) +++ fprintf(rpi->fp_reg, "YBASE:%08x CBASE:%08x\n", rpi->apb[0x8018>>2]*64, rpi->apb[0x8020>>2]*64); +++ } +++ clock_gettime(CLOCK_MONOTONIC, &tend); +++ +++ if (VERBOSE) +++ printf("%08llu: %s: OUT thread:%u phase:%d time:%llu\n", ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tfirst.tv_sec * 1000000000ULL + tfirst.tv_nsec))/1000, +++ __FUNCTION__, getthreadnum(pid), phase, ((tend.tv_sec * 1000000000ULL + tend.tv_nsec) - (tstart.tv_sec * 1000000000ULL + tstart.tv_nsec))/1000); +++ /*printf("IDL:%u RTC:%u WTC:%u RDC:%u WDC:%u RAC:%u CYC:%u CMD:%u DAT:%u RDCMD:%u RDSUB:%u WRCMD:%u WRSUB:%u MWRCMD:%u MWRSUB:%u\n", +++ rpi->sdram[IDL], rpi->sdram[RTC], rpi->sdram[WTC], rpi->sdram[RDC], rpi->sdram[WDC], rpi->sdram[RAC], rpi->sdram[CYC], rpi->sdram[CMD], rpi->sdram[DAT], +++ rpi->sdram[RDCMD], rpi->sdram[RDSUB], rpi->sdram[WRCMD], rpi->sdram[WRSUB], rpi->sdram[MWRCMD], rpi->sdram[MWRSUB]);*/ +++ +++ tstart = tend; +++} +++ +++ +++void rpi_apb_dump_regs(void *id, uint16_t addr, int num) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ int i; +++ __DMB2(); +++ if (VERBOSE) +++ for (i=0; ifp_reg, "%08x: ", 0x7eb00000 + addr + 4*i); +++ fprintf(rpi->fp_reg, "%08x", rpi->apb[(addr>>2)+i]); +++ if ((i%4)==3 || i+1 == num) +++ fprintf(rpi->fp_reg, "\n"); +++ else +++ fprintf(rpi->fp_reg, " "); +++ } +++} +++ +++void rpi_axi_dump(void *id, uint64_t addr, uint32_t size) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ int i; +++ __DMB2(); +++ if (VERBOSE) +++ for (i=0; i>2; i++) +++ { +++ if ((i%4)==0) +++ fprintf(rpi->fp_reg, "%08x: ", MANGLE(rpi->axi.vc) + (uint32_t)addr + 4*i); +++ fprintf(rpi->fp_reg, "%08x", ((uint32_t*)rpi->axi.arm)[(addr>>2)+i]); +++ if ((i%4)==3 || i+1 == size>>2) +++ fprintf(rpi->fp_reg, "\n"); +++ else +++ fprintf(rpi->fp_reg, " "); +++ } +++} +++ +++void rpi_axi_flush(void *id, int mode) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ if (CACHED) +++ { +++ gpu_clean_invalidate(&rpi->axi, mode); +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++const char * rpi_ctrl_ffmpeg_init(const char *hwaccel_device, void **id) { +++ struct RPI_DEBUG *rpi = calloc(1, sizeof(struct RPI_DEBUG)); +++ (void) hwaccel_device; +++ printf("%s\n id=%p\n", __FUNCTION__, rpi); +++ +++ if (!rpi) return "out of memory"; +++ +++ bcm_host_init(); +++ vcsm_init(); +++ rpi->apb = setup_io("/dev/argon-hevcmem", 0); +++ rpi->interrupt = setup_io("/dev/argon-intcmem", 0); +++ //rpi->sdram = setup_io(0xfe001000); +++ +++ rpi->fp_bin = stderr; +++ rpi->fp_reg = stderr; +++ +++ rpi->mbox = mbox_open(); +++ if ((CACHED ? gpu_malloc_cached_internal:gpu_malloc_uncached_internal)(rpi->mbox, AXI_MEM_SIZE, &rpi->axi) != 0) +++ return "out of memory"; +++ +++ fprintf(rpi->fp_reg, "A 100000000 apb:%p axi.arm:%p axi.vc:%08x\n", rpi->apb, rpi->axi.arm, MANGLE(rpi->axi.vc)); +++ *id = rpi; +++ return 0; +++} +++ +++void rpi_ctrl_ffmpeg_free(void *id) { +++ struct RPI_DEBUG *rpi = (struct RPI_DEBUG *) id; +++ printf("%s id=%p\n", __FUNCTION__, rpi); +++ release_io(rpi->apb); +++ release_io(rpi->interrupt); +++ gpu_free_internal(rpi->mbox, &rpi->axi); +++ printf("%s freed axi mem\n", __FUNCTION__); +++ mbox_close(rpi->mbox); +++ printf("%s closed mbox\n", __FUNCTION__); +++ free(rpi); +++ printf("%s freed rpi\n", __FUNCTION__); +++ vcsm_exit(); +++ bcm_host_deinit(); +++} ++diff --git a/libavcodec/rpi_ctrl_ffmpeg.h b/libavcodec/rpi_ctrl_ffmpeg.h ++new file mode 100644 ++index 0000000000..6a1d95f195 ++--- /dev/null +++++ b/libavcodec/rpi_ctrl_ffmpeg.h ++@@ -0,0 +1,29 @@ +++// rpi_ctrl_ffmpeg.h +++// +++// This file contains prototypes for the functions used to control the socket +++// interface when using ffmpeg. +++// +++ +++#ifndef __CTRL_FFMPEG_H__ +++#define __CTRL_FFMPEG_H__ +++ +++#include +++ +++const char *rpi_ctrl_ffmpeg_init (const char *hwaccel_device, void **id); +++void rpi_apb_write_addr (void *id, uint16_t addr, uint32_t data); +++void rpi_apb_write (void *id, uint16_t addr, uint32_t data); +++uint32_t rpi_apb_read (void *id, uint16_t addr); +++void rpi_apb_read_drop (void *id, uint16_t addr); +++void rpi_axi_write (void *id, uint64_t addr, uint32_t size, void *buf); +++void rpi_axi_read (void *id, uint64_t addr, uint32_t size, void *buf); +++void rpi_axi_read_alloc (void *id, uint32_t size); +++void rpi_axi_read_tx (void *id, uint64_t addr, uint32_t size); +++void rpi_axi_read_rx (void *id, uint32_t size, void *buf); +++void rpi_wait_interrupt (void *id, int phase); +++void rpi_ctrl_ffmpeg_free (void *id); +++uint64_t rpi_axi_get_addr (void *id); +++void rpi_apb_dump_regs(void *id, uint16_t addr, int num); +++void rpi_axi_dump(void *id, uint64_t addr, uint32_t size); +++void rpi_axi_flush(void *id, int mode); +++ +++#endif // __CTRL_FILES_H__ ++diff --git a/libavcodec/rpi_hevc.c b/libavcodec/rpi_hevc.c ++new file mode 100644 ++index 0000000000..a000077f33 ++--- /dev/null +++++ b/libavcodec/rpi_hevc.c ++@@ -0,0 +1,1065 @@ +++// FFMPEG HEVC decoder hardware accelerator +++// Andrew Holme, Argon Design Ltd +++// Copyright (c) June 2017 Raspberry Pi Ltd +++ +++#include +++#include +++ +++#include "fftools/ffmpeg.h" +++#include "libavutil/avassert.h" +++#include "libavutil/imgutils.h" +++#include "avcodec.h" +++#include "hwaccel.h" +++ +++#include "rpi_hevc.h" +++#include "rpi_zc.h" +++#include "rpi_qpu.h" +++ +++#include "rpi_ctrl_ffmpeg.h" +++////////////////////////////////////////////////////////////////////////////// +++ +++// Array of constants for scaling factors +++static const uint32_t scaling_factor_offsets[4][6] = { +++ // MID0 MID1 MID2 MID3 MID4 MID5 +++ {0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050}, // SID0 (4x4) +++ {0x0060, 0x00A0, 0x00E0, 0x0120, 0x0160, 0x01A0}, // SID1 (8x8) +++ {0x01E0, 0x02E0, 0x03E0, 0x04E0, 0x05E0, 0x06E0}, // SID2 (16x16) +++ {0x07E0, 0, 0, 0x0BE0, 0, 0}}; // SID3 (32x32) +++ +++// ffmpeg places SID3,MID1 where matrixID 3 normally is +++ +++////////////////////////////////////////////////////////////////////////////// +++// Scaling factors +++ +++static void expand_scaling_list( +++ RPI_T *rpi, +++ const ScalingList *scaling_list, // scaling list structure from ffmpeg +++ uint8_t sizeID, uint8_t matrixID) +++{ +++ uint8_t x, y, i, blkSize = 4<>1)<<3) + (x>>1); break; +++ case 3: i = ((y>>2)<<3) + (x>>2); +++ } +++ rpi->scaling_factors[index] = scaling_list->sl[sizeID][matrixID][i]; +++ } +++ } +++ if (sizeID>1) +++ rpi->scaling_factors[index_offset] = +++ scaling_list->sl_dc[sizeID-2][matrixID]; +++} +++ +++static void populate_scaling_factors(RPI_T *rpi, HEVCContext *s) { +++ const ScalingList *sl = +++ s->ps.pps->scaling_list_data_present_flag ? &s->ps.pps->scaling_list +++ : &s->ps.sps->scaling_list; +++ int sid, mid; +++ for (sid=0; sid<3; sid++) +++ for (mid=0; mid<6; mid++) +++ expand_scaling_list(rpi, sl, sid, mid); +++ +++ // second scaling matrix for 32x32 is at matrixID 3 not 1 in ffmpeg +++ expand_scaling_list(rpi, sl, 3, 0); +++ expand_scaling_list(rpi, sl, 3, 3); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Probabilities +++ +++static void populate_prob_tables(RPI_T *rpi, HEVCContext *s) { +++ struct RPI_PROB *dst = &rpi->probabilities; +++ struct FFM_PROB *src = (struct FFM_PROB *) s->HEVClc->cabac_state; +++ #define PROB_CPSZ(to, from, sz) memcpy(dst->to, src->from, sz) +++ #define PROB_COPY(to, from) memcpy(dst->to, src->from, sizeof(dst->to)) +++ memset(dst, 0, sizeof(*dst)); +++ PROB_COPY(SAO_MERGE_FLAG , sao_merge_flag ); +++ PROB_COPY(SAO_TYPE_IDX , sao_type_idx ); +++ PROB_COPY(SPLIT_FLAG , split_coding_unit_flag ); +++ PROB_COPY(CU_SKIP_FLAG , skip_flag ); +++ PROB_COPY(CU_TRANSQUANT_BYPASS_FLAG, cu_transquant_bypass_flag ); +++ PROB_COPY(PRED_MODE , pred_mode_flag ); +++ PROB_COPY(PART_SIZE , part_mode ); +++ PROB_COPY(INTRA_PRED_MODE , prev_intra_luma_pred_flag ); +++ PROB_COPY(CHROMA_PRED_MODE , intra_chroma_pred_mode ); +++ PROB_COPY(MERGE_FLAG_EXT , merge_flag ); +++ PROB_COPY(MERGE_IDX_EXT , merge_idx ); +++ PROB_COPY(INTER_DIR , inter_pred_idc ); +++ PROB_COPY(REF_PIC , ref_idx_l0 ); +++ PROB_COPY(MVP_IDX , mvp_lx_flag ); +++ PROB_CPSZ(MVD+0 , abs_mvd_greater0_flag+0 , 1); // ABS_MVD_GREATER0_FLAG[1] not used +++ PROB_CPSZ(MVD+1 , abs_mvd_greater1_flag+1 , 1); // ABS_MVD_GREATER1_FLAG[0] not used +++ PROB_COPY(QT_ROOT_CBF , no_residual_data_flag ); +++ PROB_COPY(TRANS_SUBDIV_FLAG , split_transform_flag ); +++ PROB_CPSZ(QT_CBF , cbf_luma , 2); +++ PROB_CPSZ(QT_CBF+2 , cbf_cb_cr , 4); +++ PROB_COPY(DQP , cu_qp_delta ); +++ PROB_COPY(ONE_FLAG , coeff_abs_level_greater1_flag ); +++ PROB_COPY(LASTX , last_significant_coeff_x_prefix); +++ PROB_COPY(LASTY , last_significant_coeff_y_prefix); +++ PROB_COPY(SIG_CG_FLAG , significant_coeff_group_flag ); +++ PROB_COPY(ABS_FLAG , coeff_abs_level_greater2_flag ); +++ PROB_COPY(TRANSFORMSKIP_FLAG , transform_skip_flag ); +++ PROB_CPSZ(SIG_FLAG , significant_coeff_flag , 42); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Read YUV data from socket server +++ +++static int bytes_per_line(const HEVCSPS *sps, int jump, int x) { +++ int width = FFMIN(jump, sps->width - x); +++ return sps->bit_depth>8? (width>48? 128:64) +++ : (width>64? 128:64); +++} +++ +++static void read_rect(RPI_T *rpi, char *buf, int addr64, int height, int bytes_per_line) { +++ rpi->axi_read_alloc(rpi->id, bytes_per_line*height); +++ if (bytes_per_line==128) +++ rpi->axi_read_tx(rpi->id, ((uint64_t)addr64)<<6, 128*height); +++ else { +++ int y; +++ for (y=0; yaxi_read_tx(rpi->id, ((uint64_t)addr64)<<6, 64); +++ } +++ rpi->axi_read_rx(rpi->id, bytes_per_line*height, buf); +++} +++ +++#ifdef AXI_BUFFERS +++////////////////////////////////////////////////////////////////////////////// +++// Copy YUV output data to FFMPEG frame buffer +++ +++static void copy_luma(char *buf, int bpl, int height, int x, uint8_t *data, int linesize) { +++ int y; +++ for (y=0; y> 0)&0x3ff; if(++j==linesize/2) break; +++ dst[j] = (src[i]>>10)&0x3ff; if(++j==linesize/2) break; +++ dst[j] = (src[i]>>20)&0x3ff; if(++j==linesize/2) break; +++ } +++ } +++} +++ +++static void copy_chroma10(char *buf, int bpl, int height, int x, uint8_t *u8, uint8_t *v8, int linesize) { +++ int i, j, y; +++ for (y=0; y> 0)&0x3ff; +++ v16[j] = (src[i]>>10)&0x3ff; if(++j==linesize/2) break; +++ u16[j] = (src[i]>>20)&0x3ff; i++; +++ v16[j] = (src[i]>> 0)&0x3ff; if(++j==linesize/2) break; +++ u16[j] = (src[i]>>10)&0x3ff; +++ v16[j] = (src[i]>>20)&0x3ff; if(++j==linesize/2) break; +++ } +++ } +++} +++#endif +++ +++////////////////////////////////////////////////////////////////////////////// +++// Phase 1 command and bit FIFOs +++ +++static int p1_apb_write(RPI_T *rpi, uint16_t addr, uint32_t data) { +++ if (rpi->cmd_len==rpi->cmd_max) +++ av_assert0(rpi->cmd_fifo = realloc(rpi->cmd_fifo, (rpi->cmd_max*=2)*sizeof(struct RPI_CMD))); +++ rpi->cmd_fifo[rpi->cmd_len].addr = addr; +++ rpi->cmd_fifo[rpi->cmd_len].data = data; +++ return rpi->cmd_len++; +++} +++ +++static void p1_axi_write(RPI_T *rpi, uint32_t len, const void *ptr, int cmd_idx) { +++ if (rpi->bit_len==rpi->bit_max) +++ av_assert0(rpi->bit_fifo = realloc(rpi->bit_fifo, (rpi->bit_max*=2)*sizeof(struct RPI_BIT))); +++ rpi->bit_fifo[rpi->bit_len].cmd = cmd_idx; +++ rpi->bit_fifo[rpi->bit_len].ptr = ptr; +++ rpi->bit_fifo[rpi->bit_len].len = len; +++ rpi->bit_len++; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Write probability and scaling factor memories +++ +++static void WriteProb(RPI_T *rpi) { +++ int i; +++ uint8_t *p = (uint8_t *) &rpi->probabilities; +++ for (i=0; iscaling_factors; +++ for (i=0; i= bd[i]; i++); // bd[] has num+1 elements; bd[0]=0; see hevc_ps.c +++ return i-1; +++} +++ +++static int ctb_to_slice_w_h (unsigned int ctb, int ctb_size, int width, unsigned int *bd, int num) { +++ if (ctb < bd[num-1]) return ctb_size; +++ else if (width % ctb_size) return width % ctb_size; +++ else return ctb_size; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static void alloc_picture_space(RPI_T *rpi, HEVCContext *s, int thread_idx) { +++ const HEVCSPS *sps = s->ps.sps; +++ int CtbSizeY = 1<log2_ctb_size; +++ int x64 = AXI_BASE64; +++ +++ rpi->PicWidthInCtbsY = (sps->width + CtbSizeY - 1) / CtbSizeY; //7-15 +++ rpi->PicHeightInCtbsY = (sps->height + CtbSizeY - 1) / CtbSizeY; //7-17 +++#ifdef AXI_BUFFERS +++ rpi->lumabytes64 = ((sps->height+64) * ((sps->width+95)/96) * 2); +++ rpi->framebytes64 = ((rpi->lumabytes64 * 3)/2); +++ rpi->lumastride64 = ((sps->height+64) * 128) / 64; +++ rpi->chromastride64 = (((sps->height+64) * 128 ) / 2) / 64; +++ +++ x64 += 17 * rpi->framebytes64; +++#endif +++ +++ // collocated reads/writes +++ if (sps->sps_temporal_mvp_enabled_flag) { +++ // 128 bits = 16 bytes per MV, one for every 16*16 +++ int collocatedStride64 = (rpi->PicWidthInCtbsY * (CtbSizeY/16) * 16 + 63)>>6; +++ rpi->mvframebytes64 = rpi->PicHeightInCtbsY * (CtbSizeY/16) * collocatedStride64; +++ rpi->mvstorage64 = x64; +++ x64 += rpi->mvframebytes64 * 17; // Leave space for 17 reference pictures +++ rpi->colstride64 = collocatedStride64; +++ rpi->mvstride64 = collocatedStride64; +++ } +++ +++ rpi->pubase64[0] = x64; +++} +++ +++static int alloc_stream_space(RPI_T *rpi, HEVCContext *s, int thread_idx) { +++ int stride64, x64 = rpi->pubase64[0]; +++ +++ stride64 = 1 + (rpi->max_pu_msgs*2*rpi->PicWidthInCtbsY)/64; +++ rpi->pubase64[thread_idx] = x64 + rpi->PicHeightInCtbsY*stride64 * thread_idx; +++ rpi->pustep64 = stride64; +++ x64 += rpi->PicHeightInCtbsY*stride64 * s->avctx->thread_count; +++ +++ stride64 = rpi->max_coeff64; +++ rpi->coeffbase64[thread_idx] = x64 + rpi->PicHeightInCtbsY*stride64 * thread_idx; +++ rpi->coeffstep64 = stride64; +++ x64 += rpi->PicHeightInCtbsY*stride64 * s->avctx->thread_count; +++ return x64; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Start or restart phase 1 +++ +++static void phase1_begin(RPI_T *rpi, HEVCContext *s, int thread_idx) { +++ rpi->apb_write_addr(rpi->id, RPI_PUWBASE, rpi->pubase64[thread_idx]); +++ rpi->apb_write(rpi->id, RPI_PUWSTRIDE, rpi->pustep64); +++ rpi->apb_write_addr(rpi->id, RPI_COEFFWBASE, rpi->coeffbase64[thread_idx]); +++ rpi->apb_write(rpi->id, RPI_COEFFWSTRIDE, rpi->coeffstep64); +++} +++ +++/////////////////////////////////////////////////////////////////////////////// +++// Wait until phase 2 idle +++ +++static void wait_idle(RPI_T *rpi, int last) { +++ for (;;) { +++ int order; +++ pthread_mutex_lock (&rpi->mutex_phase2); +++ order = rpi->phase2_order; +++ pthread_mutex_unlock(&rpi->mutex_phase2); +++ if (order==last) return; +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Handle PU and COEFF stream overflow +++ +++static int check_status(RPI_T *rpi) { +++ int status, c, p; +++ status = rpi->apb_read(rpi->id, RPI_STATUS); +++ p = (status>>4)&1; +++ c = (status>>3)&1; +++ if (p|c) { // overflow? +++ wait_idle(rpi, rpi->phase1_order-1); // drain phase2 before changing memory layout +++ if (p) rpi->max_pu_msgs += rpi->max_pu_msgs/2; +++ if (c) rpi->max_coeff64 += rpi->max_coeff64/2; +++ return 1; +++ } +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Write STATUS register with expected end CTU address of previous slice +++ +++static void end_previous_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { +++ const HEVCPPS *pps = s->ps.pps; +++ int last_x = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] % rpi->PicWidthInCtbsY; +++ int last_y = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] / rpi->PicWidthInCtbsY; +++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); +++} +++ +++static void wpp_pause(RPI_T *rpi, int ctb_row) { +++ p1_apb_write(rpi, RPI_STATUS, (ctb_row<<18) + 0x25); +++ p1_apb_write(rpi, RPI_TRANSFER, PROB_BACKUP); +++ p1_apb_write(rpi, RPI_MODE, ctb_row==rpi->PicHeightInCtbsY-1?0x70000:0x30000); +++ p1_apb_write(rpi, RPI_CONTROL, (ctb_row<<16) + 2); +++} +++ +++static void wpp_end_previous_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { +++ const HEVCPPS *pps = s->ps.pps; +++ int new_x = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; +++ int new_y = s->sh.slice_ctb_addr_rs / rpi->PicWidthInCtbsY; +++ int last_x = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] % rpi->PicWidthInCtbsY; +++ int last_y = pps->ctb_addr_ts_to_rs[ctb_addr_ts-1] / rpi->PicWidthInCtbsY; +++ if (rpi->wpp_entry_x<2 && (rpi->wpp_entry_y2) && rpi->PicWidthInCtbsY>2) wpp_pause(rpi, last_y); +++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); +++ if (new_x==2 || rpi->PicWidthInCtbsY==2 && rpi->wpp_entry_yps.sps; +++ const HEVCPPS *pps = s->ps.pps; +++ +++ p1_apb_write(rpi, RPI_SPS0, +++ (sps->log2_min_cb_size << 0) + +++ (sps->log2_ctb_size << 4) + +++ (sps->log2_min_tb_size << 8) + +++ (sps->log2_max_trafo_size << 12) + +++ (sps->bit_depth << 16) + +++ (sps->bit_depth << 20) + +++ (sps->max_transform_hierarchy_depth_intra << 24) + +++ (sps->max_transform_hierarchy_depth_inter << 28)); +++ +++ p1_apb_write(rpi, RPI_SPS1, +++ (sps->pcm.bit_depth << 0) + +++ (sps->pcm.bit_depth_chroma << 4) + +++ (sps->pcm.log2_min_pcm_cb_size << 8) + +++ (sps->pcm.log2_max_pcm_cb_size << 12) + +++ (sps->separate_colour_plane_flag? 0:sps->chroma_format_idc << 16) + +++ (sps->amp_enabled_flag << 18) + +++ (sps->pcm_enabled_flag << 19) + +++ (sps->scaling_list_enable_flag << 20) + +++ (sps->sps_strong_intra_smoothing_enable_flag << 21)); +++ +++ p1_apb_write(rpi, RPI_PPS, +++ (sps->log2_ctb_size - pps->diff_cu_qp_delta_depth << 0) + +++ (pps->cu_qp_delta_enabled_flag << 4) + +++ (pps->transquant_bypass_enable_flag << 5) + +++ (pps->transform_skip_enabled_flag << 6) + +++ (pps->sign_data_hiding_flag << 7) + +++ (((pps->cb_qp_offset + s->sh.slice_cb_qp_offset)&255) << 8) + +++ (((pps->cr_qp_offset + s->sh.slice_cr_qp_offset)&255) << 16) + +++ (pps->constrained_intra_pred_flag << 24)); +++ +++ if (s->ps.sps->scaling_list_enable_flag) WriteScalingFactors(rpi); +++ +++ if (!s->sh.dependent_slice_segment_flag) { +++ int ctb_col = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; +++ int ctb_row = s->sh.slice_ctb_addr_rs / rpi->PicWidthInCtbsY; +++ rpi->reg_slicestart = (ctb_col<<0) + (ctb_row<<16); +++ } +++ +++ p1_apb_write(rpi, RPI_SLICESTART, rpi->reg_slicestart); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static void write_slice(RPI_T *rpi, HEVCContext *s, uint8_t slice_w, uint8_t slice_h) { +++ uint32_t u32 = +++ (s->sh.slice_type << 12) +++ + (s->sh.slice_sample_adaptive_offset_flag[0] << 14) +++ + (s->sh.slice_sample_adaptive_offset_flag[1] << 15) +++ + (slice_w << 17) +++ + (slice_h << 24); +++ +++ if (s->sh.slice_type==HEVC_SLICE_B || s->sh.slice_type==HEVC_SLICE_P) u32 |= +++ (s->sh.max_num_merge_cand << 0) +++ + (s->sh.nb_refs[L0] << 4) +++ + (s->sh.nb_refs[L1] << 8); +++ +++ if (s->sh.slice_type==HEVC_SLICE_B) u32 |= s->sh.mvd_l1_zero_flag<<16; +++ p1_apb_write(rpi, RPI_SLICE, u32); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Wavefront mode +++ +++static void wpp_entry_point(RPI_T *rpi, HEVCContext *s, int do_bte, int resetQPY, int ctb_addr_ts) { +++ const HEVCSPS *sps = s->ps.sps; +++ const HEVCPPS *pps = s->ps.pps; +++ +++ int ctb_size = 1<log2_ctb_size; +++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; +++ +++ int ctb_col = rpi->wpp_entry_x = ctb_addr_rs % rpi->PicWidthInCtbsY; +++ int ctb_row = rpi->wpp_entry_y = ctb_addr_rs / rpi->PicWidthInCtbsY; +++ +++ int endx = rpi->PicWidthInCtbsY-1; +++ int endy = ctb_row; +++ +++ uint8_t slice_w = ctb_to_slice_w_h(ctb_col, ctb_size, sps->width, pps->col_bd, pps->num_tile_columns); +++ uint8_t slice_h = ctb_to_slice_w_h(ctb_row, ctb_size, sps->height, pps->row_bd, pps->num_tile_rows); +++ +++ p1_apb_write(rpi, RPI_TILESTART, 0); +++ p1_apb_write(rpi, RPI_TILEEND, endx + (endy<<16)); +++ +++ if (do_bte) p1_apb_write(rpi, RPI_BEGINTILEEND, endx + (endy<<16)); +++ +++ write_slice(rpi, s, slice_w, ctb_row==rpi->PicHeightInCtbsY-1? slice_h : ctb_size); +++ +++ if (resetQPY) p1_apb_write(rpi, RPI_QP, sps->qp_bd_offset + s->sh.slice_qp); +++ +++ p1_apb_write(rpi, RPI_MODE, ctb_row==rpi->PicHeightInCtbsY-1? 0x60001 : 0x20001); +++ p1_apb_write(rpi, RPI_CONTROL, (ctb_col<<0) + (ctb_row<<16)); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Tiles mode +++ +++static void new_entry_point(RPI_T *rpi, HEVCContext *s, int do_bte, int resetQPY, int ctb_addr_ts) { +++ const HEVCSPS *sps = s->ps.sps; +++ const HEVCPPS *pps = s->ps.pps; +++ +++ int ctb_col = pps->ctb_addr_ts_to_rs[ctb_addr_ts] % rpi->PicWidthInCtbsY; +++ int ctb_row = pps->ctb_addr_ts_to_rs[ctb_addr_ts] / rpi->PicWidthInCtbsY; +++ +++ int tile_x = ctb_to_tile (ctb_col, pps->col_bd, pps->num_tile_columns); +++ int tile_y = ctb_to_tile (ctb_row, pps->row_bd, pps->num_tile_rows); +++ +++ int endx = pps->col_bd[tile_x+1] - 1; +++ int endy = pps->row_bd[tile_y+1] - 1; +++ +++ uint8_t slice_w = ctb_to_slice_w_h(ctb_col, 1<log2_ctb_size, sps->width, pps->col_bd, pps->num_tile_columns); +++ uint8_t slice_h = ctb_to_slice_w_h(ctb_row, 1<log2_ctb_size, sps->height, pps->row_bd, pps->num_tile_rows); +++ +++ p1_apb_write(rpi, RPI_TILESTART, pps->col_bd[tile_x] + (pps->row_bd[tile_y]<<16)); +++ p1_apb_write(rpi, RPI_TILEEND, endx + (endy<<16)); +++ +++ if (do_bte) p1_apb_write(rpi, RPI_BEGINTILEEND, endx + (endy<<16)); +++ +++ write_slice(rpi, s, slice_w, slice_h); +++ +++ if (resetQPY) p1_apb_write(rpi, RPI_QP, sps->qp_bd_offset + s->sh.slice_qp); +++ +++ p1_apb_write(rpi, RPI_MODE, (0xFFFF << 0) +++ + (0x0 << 16) +++ + ((tile_x==pps->num_tile_columns-1) << 17) +++ + ((tile_y==pps->num_tile_rows-1) << 18)); +++ +++ p1_apb_write(rpi, RPI_CONTROL, (ctb_col<<0) + (ctb_row<<16)); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Workaround for 3 December 2016 commit 8dfba25ce89b62c80ba83e2116d549176c376144 +++// https://github.com/libav/libav/commit/8dfba25ce89b62c80ba83e2116d549176c376144 +++// This commit prevents multi-threaded hardware acceleration by locking hwaccel_mutex +++// around codec->decode() calls. Workaround is to unlock and relock before returning. +++ +++static void hwaccel_mutex(AVCodecContext *avctx, int (*action) (pthread_mutex_t *)) { +++ struct FrameThreadContext { +++ void *foo1, *foo2; // must match struct layout in pthread_frame.c +++ pthread_mutex_t foo3, hwaccel_mutex; +++ }; +++ struct PerThreadContext { +++ struct FrameThreadContext *parent; +++ }; +++ struct PerThreadContext *p = avctx->internal->thread_ctx; +++ if (avctx->thread_count>1) action(&p->parent->hwaccel_mutex); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int get_thread_idx(RPI_T *rpi, AVCodecContext *avctx) { +++ int idx; +++ for (idx=0; idxthread_avctx[idx]==avctx) break; +++ av_assert0(idxinternal->hwaccel_priv_data; +++ HEVCContext *s = avctx->priv_data; +++ +++ int thread_idx = get_thread_idx(rpi, 0); // Find first free slot +++ +++ rpi->thread_avctx[thread_idx] = avctx; +++ rpi->thread_order[thread_idx] = rpi->decode_order++; +++ +++ ff_thread_finish_setup(avctx); // Allow next thread to enter rpi_hevc_start_frame +++ hwaccel_mutex(avctx, pthread_mutex_unlock); +++ +++ // Enforcing phase 1 order precludes busy waiting for phase 2 +++ for (;;) { +++ pthread_mutex_lock (&rpi->mutex_phase1); +++ if (rpi->thread_order[thread_idx]==rpi->phase1_order) break; +++ pthread_mutex_unlock(&rpi->mutex_phase1); +++ } +++ rpi->phase1_order++; +++ +++ alloc_picture_space(rpi, s, thread_idx); +++ rpi->bit_len = rpi->cmd_len = 0; +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Slice messages +++ +++static void msg_slice(RPI_T *rpi, uint16_t msg) { +++ rpi->slice_msgs[rpi->num_slice_msgs++] = msg; +++} +++ +++static void program_slicecmds(RPI_T *rpi, int sliceid) { +++ int i; +++ p1_apb_write(rpi, RPI_SLICECMDS, rpi->num_slice_msgs+(sliceid<<8)); +++ for(i=0; inum_slice_msgs; i++) { +++ p1_apb_write(rpi, 0x4000+4*i, rpi->slice_msgs[i] & 0xffff); +++ } +++} +++ +++static void pre_slice_decode(RPI_T *rpi, HEVCContext *s) { +++ const HEVCSPS *sps = s->ps.sps; +++ const HEVCPPS *pps = s->ps.pps; +++ SliceHeader *sh = &s->sh; +++ +++ int weightedPredFlag, i, rIdx; +++ uint16_t cmd_slice; +++ +++ rpi->num_slice_msgs=0; +++ cmd_slice = 0; +++ if (sh->slice_type==HEVC_SLICE_I) cmd_slice = 1; +++ if (sh->slice_type==HEVC_SLICE_P) cmd_slice = 2; +++ if (sh->slice_type==HEVC_SLICE_B) cmd_slice = 3; +++ +++ if (sh->slice_type!=HEVC_SLICE_I) { +++ cmd_slice += sh->nb_refs[L0]<<2; +++ cmd_slice += sh->nb_refs[L1]<<6; +++ } +++ if (sh->slice_type==HEVC_SLICE_P +++ || sh->slice_type==HEVC_SLICE_B) rpi->max_num_merge_cand = sh->max_num_merge_cand; +++ +++ cmd_slice += rpi->max_num_merge_cand<<11; +++ +++ if (sh->slice_temporal_mvp_enabled_flag) { +++ if (sh->slice_type==HEVC_SLICE_B) rpi->collocated_from_l0_flag = sh->collocated_list==L0; +++ else if (sh->slice_type==HEVC_SLICE_P) rpi->collocated_from_l0_flag = 1; +++ } +++ cmd_slice += rpi->collocated_from_l0_flag<<14; +++ +++ if (sh->slice_type==HEVC_SLICE_P || sh->slice_type==HEVC_SLICE_B) { +++ +++ int NoBackwardPredFlag = 1; // Flag to say all reference pictures are from the past +++ for(i=L0; i<=L1; i++) { +++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { +++ HEVCFrame *f = s->ref->refPicList[i].ref[rIdx]; +++ HEVCFrame *c = s->ref; // CurrentPicture +++ if (c->poc < f->poc) NoBackwardPredFlag = 0; +++ } +++ } +++ +++ rpi->collocated_ref_idx = sh->collocated_ref_idx; +++ if (s->ref->refPicList && s->ref->collocated_ref) +++ for (i=0; inb_refs[L1]) rpi->RefPicList[1][i] = s->ref->refPicList[1].ref[i] - s->DPB; +++ if (inb_refs[L0]) rpi->RefPicList[0][i] = s->ref->refPicList[0].ref[i] - s->DPB; +++ } +++ +++ cmd_slice += NoBackwardPredFlag<<10; +++ msg_slice(rpi, cmd_slice); +++ +++ // Write reference picture descriptions +++ weightedPredFlag = sh->slice_type==HEVC_SLICE_P? pps->weighted_pred_flag : pps->weighted_bipred_flag; +++ +++ for(i=L0; i<=L1; i++) +++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { +++ HEVCFrame *f = s->ref->refPicList[i].ref[rIdx]; +++ HEVCFrame *c = s->ref; // CurrentPicture +++ int pic = f - s->DPB; +++ // Make sure pictures are in range 0 to 15 +++ int adjusted_pic = fref->refPicList[i].isLongTerm[rIdx]; +++ msg_slice(rpi, adjusted_pic+(lt<<4)+(weightedPredFlag<<5)+(weightedPredFlag<<6)); +++ msg_slice(rpi, f->poc); +++ if (weightedPredFlag) { +++ msg_slice(rpi, s->sh.luma_log2_weight_denom+(((i?s-> sh.luma_weight_l1: s->sh.luma_weight_l0)[rIdx] &0x1ff)<<3)); +++ msg_slice(rpi, (i?s-> sh.luma_offset_l1: s->sh.luma_offset_l0)[rIdx] & 0xff); +++ msg_slice(rpi, s->sh.chroma_log2_weight_denom+(((i?s->sh.chroma_weight_l1:s->sh.chroma_weight_l0)[rIdx][0]&0x1ff)<<3)); +++ msg_slice(rpi, (i?s->sh.chroma_offset_l1:s->sh.chroma_offset_l0)[rIdx][0]& 0xff); +++ msg_slice(rpi, s->sh.chroma_log2_weight_denom+(((i?s->sh.chroma_weight_l1:s->sh.chroma_weight_l0)[rIdx][1]&0x1ff)<<3)); +++ msg_slice(rpi, (i?s->sh.chroma_offset_l1:s->sh.chroma_offset_l0)[rIdx][1]& 0xff); +++ } +++ } +++ } +++ else +++ msg_slice(rpi, cmd_slice); +++ +++ msg_slice(rpi, ((sh->beta_offset/2)&15) +++ + (((sh->tc_offset/2)&15) << 4) +++ + (sh->disable_deblocking_filter_flag << 8) +++ + (sh->slice_loop_filter_across_slices_enabled_flag << 9) +++ + (pps->loop_filter_across_tiles_enabled_flag << 10)); // CMD_DEBLOCK +++ +++ msg_slice(rpi, ((sh->slice_cr_qp_offset&31)<<5) + (sh->slice_cb_qp_offset&31)); // CMD_QPOFF +++ +++ // collocated reads/writes +++ if (sps->sps_temporal_mvp_enabled_flag) { +++ int thread_idx = get_thread_idx(rpi, s->avctx); +++ int CurrentPicture = s->ref - s->DPB; +++ int colPic = rpi->RefPicList[sh->slice_type==HEVC_SLICE_B && rpi->collocated_from_l0_flag==0][rpi->collocated_ref_idx]; +++ rpi->mvbase64 [thread_idx] = rpi->mvstorage64 + CurrentPicture * rpi->mvframebytes64; +++ if (sh->slice_type==HEVC_SLICE_I) { +++ // Collocated picture not well defined here. Use mvbase or previous value +++ if (sh->first_slice_in_pic_flag) +++ rpi->colbase64[thread_idx] = rpi->mvbase64[thread_idx]; // Ensure we don't read garbage +++ } +++ else +++ rpi->colbase64[thread_idx] = rpi->mvstorage64 + colPic * rpi->mvframebytes64; +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// End frame +++ +++static int rpi_hevc_end_frame(AVCodecContext *avctx) { +++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; +++ HEVCContext *s = avctx->priv_data; +++ const HEVCPPS *pps = s->ps.pps; +++ const HEVCSPS *sps = s->ps.sps; +++ int thread_idx = get_thread_idx(rpi, avctx); +++ int jump = sps->bit_depth>8?96:128; +++ int CurrentPicture = s->ref - s->DPB; +++ AVFrame *f = s->ref->frame; +++ int last_x = pps->col_bd[pps->num_tile_columns]-1; +++ int last_y = pps->row_bd[pps->num_tile_rows]-1; +++ +++ int i, a64, x; +++ char *buf; +++ +++ // End of phase 1 command compilation +++ if (pps->entropy_coding_sync_enabled_flag) { +++ if (rpi->wpp_entry_x<2 && rpi->PicWidthInCtbsY>2) wpp_pause(rpi, last_y); +++ } +++ p1_apb_write(rpi, RPI_STATUS, 1 + (last_x<<5) + (last_y<<18)); +++ +++ // Phase 1 ... +++ for (;;) { +++ // (Re-)allocate PU/COEFF stream space +++ a64 = alloc_stream_space(rpi, s, thread_idx); +++ // Send bitstream data +++ for (i=0; ibit_len; i++) { +++ rpi->axi_write(rpi->id, ((uint64_t)a64)<<6, rpi->bit_fifo[i].len, rpi->bit_fifo[i].ptr); +++ rpi->cmd_fifo[rpi->bit_fifo[i].cmd].data = a64 + (rpi->axi_get_addr(rpi->id)>>6); // Set BFBASE +++ a64 += (rpi->bit_fifo[i].len+63)/64; +++ } +++ // Send phase 1 commands (cache flush on real hardware) +++ rpi->axi_write(rpi->id, ((uint64_t)a64)<<6, rpi->cmd_len * sizeof(struct RPI_CMD), rpi->cmd_fifo); +++ rpi->axi_flush(rpi->id, 3); +++ phase1_begin(rpi, s, thread_idx); +++ // Trigger command FIFO +++ rpi->apb_write(rpi->id, RPI_CFNUM, rpi->cmd_len); +++ rpi->apb_dump_regs(rpi->id, 0x0, 32); +++ rpi->apb_dump_regs(rpi->id, 0x8000, 24); +++ rpi->axi_dump(rpi->id, ((uint64_t)a64)<<6, rpi->cmd_len * sizeof(struct RPI_CMD)); +++ rpi->apb_write_addr(rpi->id, RPI_CFBASE, a64); +++ rpi->wait_interrupt(rpi->id, 1); +++ if (check_status(rpi)==0) break; // No PU/COEFF overflow? +++ } +++ pthread_mutex_unlock(&rpi->mutex_phase1); +++ +++ // Phase 2 ... +++ for (;;) { +++ pthread_mutex_lock (&rpi->mutex_phase2); +++ if (rpi->thread_order[thread_idx]==rpi->phase2_order) break; +++ pthread_mutex_unlock(&rpi->mutex_phase2); +++ } +++ rpi->phase2_order++; +++ +++ rpi->apb_write_addr(rpi->id, RPI_PURBASE, rpi->pubase64[thread_idx]); +++ rpi->apb_write(rpi->id, RPI_PURSTRIDE, rpi->pustep64); +++ rpi->apb_write_addr(rpi->id, RPI_COEFFRBASE, rpi->coeffbase64[thread_idx]); +++ rpi->apb_write(rpi->id, RPI_COEFFRSTRIDE, rpi->coeffstep64); +++ +++#if !defined(AXI_BUFFERS) +++#define MANGLE(x) (((x) &~0xc0000000)>>6) +++{ +++ const AVRpiZcRefPtr fr_buf = f ? av_rpi_zc_ref(avctx, f, f->format, 0) : NULL; +++ uint32_t handle = fr_buf ? av_rpi_zc_vc_handle(fr_buf):0; +++// printf("%s cur:%d fr:%p handle:%d YUV:%x:%x ystride:%d ustride:%d ah:%d\n", __FUNCTION__, CurrentPicture, f, handle, get_vc_address_y(f), get_vc_address_u(f), f->linesize[0], f->linesize[1], f->linesize[3]); +++ rpi->apb_write(rpi->id, RPI_OUTYBASE, MANGLE(get_vc_address_y(f))); +++ rpi->apb_write(rpi->id, RPI_OUTCBASE, MANGLE(get_vc_address_u(f))); +++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, f->linesize[3] * 128 / 64); +++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, f->linesize[3] * 128 / 64); +++ av_rpi_zc_unref(fr_buf); +++} +++#else +++ // Output frame and reference picture locations +++ rpi->apb_write_addr(rpi->id, RPI_OUTYBASE, CurrentPicture * rpi->framebytes64); +++ rpi->apb_write_addr(rpi->id, RPI_OUTCBASE, CurrentPicture * rpi->framebytes64 + rpi->lumabytes64); +++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, rpi->lumastride64); +++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, rpi->chromastride64); +++#endif +++ +++#if !defined(AXI_BUFFERS) +++{ +++ SliceHeader *sh = &s->sh; +++ int rIdx; +++ for(i=0; i<16; i++) { +++ rpi->apb_write(rpi->id, 0x9000+16*i, 0); +++ rpi->apb_write(rpi->id, 0x9004+16*i, 0); +++ rpi->apb_write(rpi->id, 0x9008+16*i, 0); +++ rpi->apb_write(rpi->id, 0x900C+16*i, 0); +++ } +++ +++ for(i=L0; i<=L1; i++) +++ for(rIdx=0; rIdx nb_refs[i]; rIdx++) { +++ HEVCFrame *f1 = s->ref->refPicList[i].ref[rIdx]; +++ HEVCFrame *c = s->ref; // CurrentPicture +++ int pic = f1 - s->DPB; +++ // Make sure pictures are in range 0 to 15 +++ int adjusted_pic = f1DPB[pic]; +++ AVFrame *fr = hevc ? hevc->frame : NULL; +++ const AVRpiZcRefPtr fr_buf = fr ? av_rpi_zc_ref(avctx, fr, fr->format, 0) : NULL; +++ uint32_t handle = fr_buf ? av_rpi_zc_vc_handle(fr_buf):0; +++// printf("%s pic:%d (%d,%d,%d) fr:%p handle:%d YUV:%x:%x\n", __FUNCTION__, adjusted_pic, i, rIdx, pic, fr, handle, get_vc_address_y(fr), get_vc_address_u(fr)); +++ rpi->apb_write(rpi->id, 0x9000+16*adjusted_pic, MANGLE(get_vc_address_y(fr))); +++ rpi->apb_write(rpi->id, 0x9008+16*adjusted_pic, MANGLE(get_vc_address_u(fr))); +++ rpi->apb_write(rpi->id, RPI_OUTYSTRIDE, fr->linesize[3] * 128 / 64); +++ rpi->apb_write(rpi->id, RPI_OUTCSTRIDE, fr->linesize[3] * 128 / 64); +++ av_rpi_zc_unref(fr_buf); +++ } +++} +++#else +++ for(i=0; i<16; i++) { +++ int pic = i < CurrentPicture ? i : i+1; +++ rpi->apb_write_addr(rpi->id, 0x9000+16*i, pic * rpi->framebytes64); +++ rpi->apb_write(rpi->id, 0x9004+16*i, rpi->lumastride64); +++ rpi->apb_write_addr(rpi->id, 0x9008+16*i, pic * rpi->framebytes64 + rpi->lumabytes64); +++ rpi->apb_write(rpi->id, 0x900C+16*i, rpi->chromastride64); +++ } +++#endif +++ +++ rpi->apb_write(rpi->id, RPI_CONFIG2, +++ (sps->bit_depth << 0) // BitDepthY +++ + (sps->bit_depth << 4) // BitDepthC +++ + ((sps->bit_depth>8) << 8) // BitDepthY +++ + ((sps->bit_depth>8) << 9) // BitDepthC +++ + (sps->log2_ctb_size <<10) +++ + (pps->constrained_intra_pred_flag <<13) +++ + (sps->sps_strong_intra_smoothing_enable_flag<<14) +++ + (sps->sps_temporal_mvp_enabled_flag <<15) +++ + (pps->log2_parallel_merge_level <<16) +++ + (s->sh.slice_temporal_mvp_enabled_flag <<19) +++ + (sps->pcm.loop_filter_disable_flag <<20) +++ + ((pps->cb_qp_offset&31) <<21) +++ + ((pps->cr_qp_offset&31) <<26)); +++ +++ rpi->apb_write(rpi->id, RPI_FRAMESIZE, (sps->height<<16) + sps->width); +++ rpi->apb_write(rpi->id, RPI_CURRPOC, s->poc); +++ +++ // collocated reads/writes +++ if (sps->sps_temporal_mvp_enabled_flag) { +++ rpi->apb_write(rpi->id, RPI_COLSTRIDE, rpi->colstride64); +++ rpi->apb_write(rpi->id, RPI_MVSTRIDE, rpi->mvstride64); +++ rpi->apb_write_addr(rpi->id, RPI_MVBASE, rpi->mvbase64 [thread_idx]); +++ rpi->apb_write_addr(rpi->id, RPI_COLBASE, rpi->colbase64[thread_idx]); +++ } +++ +++ rpi->apb_dump_regs(rpi->id, 0x0, 32); +++ rpi->apb_dump_regs(rpi->id, 0x8000, 24); +++ rpi->apb_write(rpi->id, RPI_NUMROWS, rpi->PicHeightInCtbsY); +++ rpi->apb_read_drop(rpi->id, RPI_NUMROWS); // Read back to confirm write has reached block +++ rpi->wait_interrupt(rpi->id, 2); +++ +++//printf("%s: %dx%d %d\n", __FUNCTION__, f->width, f->height, f->linesize[0]); +++#if defined(AXI_BUFFERS) +++ // Copy YUV output frame +++ av_assert0(buf = malloc(128*sps->height)); +++ a64 = AXI_BASE64 + CurrentPicture * rpi->framebytes64; +++ for(x=0; xwidth; x+=jump) { +++ int bpl = bytes_per_line(sps, jump, x); +++ read_rect(rpi, buf, a64, sps->height, bpl); +++ (sps->bit_depth>8?copy_luma10:copy_luma)(buf, bpl, sps->height, x, f->data[0], f->linesize[0]); +++ a64 += rpi->lumastride64; +++ } +++ a64 = AXI_BASE64 + CurrentPicture * rpi->framebytes64 + rpi->lumabytes64; +++ for(x=0; xwidth; x+=jump) { +++ int bpl = bytes_per_line(sps, jump, x); +++ read_rect(rpi, buf, a64, sps->height/2, bpl); +++ (sps->bit_depth>8?copy_chroma10:copy_chroma)(buf, bpl, sps->height/2, x/2, f->data[1], f->data[2], f->linesize[1]); +++ a64 += rpi->chromastride64; +++ } +++ free(buf); +++#endif +++ rpi->thread_avctx[thread_idx] = 0; +++ pthread_mutex_unlock(&rpi->mutex_phase2); +++ hwaccel_mutex(avctx, pthread_mutex_lock); +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static void WriteBitstream(RPI_T *rpi, HEVCContext *s) { +++ const int rpi_use_emu = 0; // FFmpeg removes emulation prevention bytes +++ const int offset = 0; // Always 64-byte aligned in sim, need not be on real hardware +++ GetBitContext *gb = &s->HEVClc->gb; +++ int len = 1 + gb->size_in_bits/8 - gb->index/8; +++ const void *ptr = &gb->buffer[gb->index/8]; +++ +++ p1_axi_write(rpi, len, ptr, p1_apb_write(rpi, RPI_BFBASE, 0)); // BFBASE set later +++ p1_apb_write(rpi, RPI_BFNUM, len); +++ p1_apb_write(rpi, RPI_BFCONTROL, offset + (1<<7)); // Stop +++ p1_apb_write(rpi, RPI_BFCONTROL, offset + (rpi_use_emu<<6)); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Wavefront mode +++ +++static void wpp_decode_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { +++ const HEVCPPS *pps = s->ps.pps; +++ +++ int i, resetQPY=1; +++ int indep = !s->sh.dependent_slice_segment_flag; +++ int ctb_col = s->sh.slice_ctb_addr_rs % rpi->PicWidthInCtbsY; +++ +++ if (ctb_addr_ts) wpp_end_previous_slice(rpi, s, ctb_addr_ts); +++ pre_slice_decode(rpi, s); +++ WriteBitstream(rpi, s); +++ if (ctb_addr_ts==0 || indep || rpi->PicWidthInCtbsY==1) WriteProb(rpi); +++ else if (ctb_col==0) p1_apb_write(rpi, RPI_TRANSFER, PROB_RELOAD); +++ else resetQPY=0; +++ program_slicecmds(rpi, s->slice_idx); +++ new_slice_segment(rpi, s); +++ wpp_entry_point(rpi, s, indep, resetQPY, ctb_addr_ts); +++ for (i=0; ish.num_entry_point_offsets; i++) { +++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; +++ int ctb_row = ctb_addr_rs / rpi->PicWidthInCtbsY; +++ int last_x = rpi->PicWidthInCtbsY-1; +++ if (rpi->PicWidthInCtbsY>2) wpp_pause(rpi, ctb_row); +++ p1_apb_write(rpi, RPI_STATUS, (ctb_row<<18) + (last_x<<5) + 2); +++ if (rpi->PicWidthInCtbsY==2) p1_apb_write(rpi, RPI_TRANSFER, PROB_BACKUP); +++ if (rpi->PicWidthInCtbsY==1) WriteProb(rpi); +++ else p1_apb_write(rpi, RPI_TRANSFER, PROB_RELOAD); +++ ctb_addr_ts += pps->column_width[0]; +++ wpp_entry_point(rpi, s, 0, 1, ctb_addr_ts); +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Tiles mode +++ +++static void decode_slice(RPI_T *rpi, HEVCContext *s, int ctb_addr_ts) { +++ const HEVCPPS *pps = s->ps.pps; +++ int i, resetQPY; +++ +++ if (ctb_addr_ts) end_previous_slice(rpi, s, ctb_addr_ts); +++ pre_slice_decode(rpi, s); +++ WriteBitstream(rpi, s); +++ resetQPY = ctb_addr_ts==0 +++ || pps->tile_id[ctb_addr_ts]!=pps->tile_id[ctb_addr_ts-1] +++ || !s->sh.dependent_slice_segment_flag; +++ if (resetQPY) WriteProb(rpi); +++ program_slicecmds(rpi, s->slice_idx); +++ new_slice_segment(rpi, s); +++ new_entry_point(rpi, s, !s->sh.dependent_slice_segment_flag, resetQPY, ctb_addr_ts); +++ for (i=0; ish.num_entry_point_offsets; i++) { +++ int ctb_addr_rs = pps->ctb_addr_ts_to_rs[ctb_addr_ts]; +++ int ctb_col = ctb_addr_rs % rpi->PicWidthInCtbsY; +++ int ctb_row = ctb_addr_rs / rpi->PicWidthInCtbsY; +++ int tile_x = ctb_to_tile (ctb_col, pps->col_bd, pps->num_tile_columns); +++ int tile_y = ctb_to_tile (ctb_row, pps->row_bd, pps->num_tile_rows); +++ int last_x = pps->col_bd[tile_x+1]-1; +++ int last_y = pps->row_bd[tile_y+1]-1; +++ p1_apb_write(rpi, RPI_STATUS, 2 + (last_x<<5) + (last_y<<18)); +++ WriteProb(rpi); +++ ctb_addr_ts += pps->column_width[tile_x] * pps->row_height[tile_y]; +++ new_entry_point(rpi, s, 0, 1, ctb_addr_ts); +++ } +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int rpi_hevc_decode_slice( +++ AVCodecContext *avctx, +++ const uint8_t *buffer, +++ uint32_t size) { +++ +++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; +++ HEVCContext *s = avctx->priv_data; +++ const HEVCPPS *pps = s->ps.pps; +++ int ctb_addr_ts = pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]; +++ ff_hevc_cabac_init(s, ctb_addr_ts); +++ if (s->ps.sps->scaling_list_enable_flag) populate_scaling_factors(rpi, s); +++ populate_prob_tables(rpi, s); +++ pps->entropy_coding_sync_enabled_flag? wpp_decode_slice(rpi, s, ctb_addr_ts) +++ : decode_slice(rpi, s, ctb_addr_ts); +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++// Bind to socket client +++ +++static int open_socket_client(RPI_T *rpi, const char *so) { +++ *(void **) &rpi->ctrl_ffmpeg_init = rpi_ctrl_ffmpeg_init; +++ *(void **) &rpi->apb_write = rpi_apb_write; +++ *(void **) &rpi->apb_write_addr = rpi_apb_write_addr; +++ *(void **) &rpi->apb_read = rpi_apb_read; +++ *(void **) &rpi->apb_read_drop = rpi_apb_read_drop; +++ *(void **) &rpi->axi_write = rpi_axi_write; +++ *(void **) &rpi->axi_read_alloc = rpi_axi_read_alloc; +++ *(void **) &rpi->axi_read_tx = rpi_axi_read_tx; +++ *(void **) &rpi->axi_read_rx = rpi_axi_read_rx; +++ *(void **) &rpi->axi_get_addr = rpi_axi_get_addr; +++ *(void **) &rpi->apb_dump_regs = rpi_apb_dump_regs; +++ *(void **) &rpi->axi_dump = rpi_axi_dump; +++ *(void **) &rpi->axi_flush = rpi_axi_flush; +++ *(void **) &rpi->wait_interrupt = rpi_wait_interrupt; +++ *(void **) &rpi->ctrl_ffmpeg_free = rpi_ctrl_ffmpeg_free; +++ return 1; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int rpi_hevc_alloc_frame(AVCodecContext *avctx, AVFrame *f) { +++ HEVCContext *s = avctx->priv_data; +++ const HEVCSPS *sps = s->ps.sps; +++ const int ALIGN = 16; +++ +++ f->width = sps->width; +++ f->height = sps->height; +++ f->format = sps->pix_fmt; +++ f->buf[0] = av_buffer_alloc(1); +++ f->buf[1] = av_buffer_alloc(1); +++ f->buf[2] = av_buffer_alloc(1); +++ return av_image_alloc(f->data, f->linesize, f->width, f->height, f->format, ALIGN); +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int rpi_hevc_init(AVCodecContext *avctx) { +++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; +++ const char *err, *so; +++ +++ so = "./rpi_ffmpeg.so"; +++ +++ if (avctx->width>4096 || avctx->height>4096) { +++ av_log(NULL, AV_LOG_FATAL, "Picture size %dx%d exceeds 4096x4096 maximum for HWAccel\n", avctx->width, avctx->height); +++ return AVERROR(ENOTSUP); +++ } +++ if (!open_socket_client(rpi, so)) { +++ av_log(NULL, AV_LOG_FATAL, "%s\n", dlerror()); +++ return AVERROR_EXTERNAL; +++ } +++ err = rpi->ctrl_ffmpeg_init(NULL, &rpi->id); +++ if (err) { +++ av_log(NULL, AV_LOG_FATAL, "Could not connect to RPI server: %s\n", err); +++ return AVERROR_EXTERNAL; +++ } +++ +++#ifdef RPI_DISPLAY +++ #include "rpi_zc.h" +++ // Whilst FFmpegs init fn is only called once the close fn is called as +++ // many times as we have threads (init_thread_copy is called for the +++ // threads). So to match init & term put the init here where it will be +++ // called by both init & copy +++ av_rpi_zc_init(avctx); +++#endif +++ +++ pthread_mutex_init(&rpi->mutex_phase1, NULL); +++ pthread_mutex_init(&rpi->mutex_phase2, NULL); +++ +++ // Initial PU/COEFF stream buffer sizes chosen so jellyfish40.265 requires 1 overflow/restart +++ rpi->max_pu_msgs = 2+340; // 7.2 says at most 1611 messages per CTU +++ rpi->max_coeff64 = 2+1404; +++ +++ av_assert0(rpi->cmd_fifo = malloc((rpi->cmd_max=1024)*sizeof(struct RPI_CMD))); +++ av_assert0(rpi->bit_fifo = malloc((rpi->bit_max=1024)*sizeof(struct RPI_BIT))); +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++static int rpi_hevc_free(AVCodecContext *avctx) { +++ RPI_T *rpi = avctx->internal->hwaccel_priv_data; +++ if (rpi->decode_order) wait_idle(rpi, rpi->decode_order); +++ if (rpi->cmd_fifo) free(rpi->cmd_fifo); +++ if (rpi->bit_fifo) free(rpi->bit_fifo); +++ pthread_mutex_destroy(&rpi->mutex_phase1); +++ pthread_mutex_destroy(&rpi->mutex_phase2); +++ if (rpi->id && rpi->ctrl_ffmpeg_free) rpi->ctrl_ffmpeg_free(rpi->id); +++ return 0; +++} +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++const AVHWAccel ff_hevc_rpi4_8_hwaccel = { +++ .name = "hevc_rpi4_8", +++ .type = AVMEDIA_TYPE_VIDEO, +++ .id = AV_CODEC_ID_HEVC, +++ .pix_fmt = AV_PIX_FMT_RPI4_8, +++ //.alloc_frame = rpi_hevc_alloc_frame, +++ .start_frame = rpi_hevc_start_frame, +++ .end_frame = rpi_hevc_end_frame, +++ .decode_slice = rpi_hevc_decode_slice, +++ .init = rpi_hevc_init, +++ .uninit = rpi_hevc_free, +++ .priv_data_size = sizeof(RPI_T), +++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +++}; +++ +++const AVHWAccel ff_hevc_rpi4_10_hwaccel = { +++ .name = "hevc_rpi4_10", +++ .type = AVMEDIA_TYPE_VIDEO, +++ .id = AV_CODEC_ID_HEVC, +++ .pix_fmt = AV_PIX_FMT_RPI4_10, +++ //.alloc_frame = rpi_hevc_alloc_frame, +++ .start_frame = rpi_hevc_start_frame, +++ .end_frame = rpi_hevc_end_frame, +++ .decode_slice = rpi_hevc_decode_slice, +++ .init = rpi_hevc_init, +++ .uninit = rpi_hevc_free, +++ .priv_data_size = sizeof(RPI_T), +++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +++}; +++ +++ +++int rpi_init(AVCodecContext *avctx) { +++ return 0; +++} ++diff --git a/libavcodec/rpi_hevc.h b/libavcodec/rpi_hevc.h ++new file mode 100644 ++index 0000000000..f54657a957 ++--- /dev/null +++++ b/libavcodec/rpi_hevc.h ++@@ -0,0 +1,219 @@ +++// FFMPEG HEVC decoder hardware accelerator +++// Andrew Holme, Argon Design Ltd +++// Copyright (c) June 2017 Raspberry Pi Ltd +++ +++#include +++#include +++ +++#include "hevc.h" +++#include "hevcdec.h" +++ +++#define MAX_THREADS 50 +++#define NUM_SCALING_FACTORS 4064 +++ +++#define AXI_BASE64 0 +++ +++#define PROB_BACKUP ((20<<12) + (20<<6) + (0<<0)) +++#define PROB_RELOAD ((20<<12) + (20<<0) + (0<<6)) +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++#define RPI_SPS0 0 +++#define RPI_SPS1 4 +++#define RPI_PPS 8 +++#define RPI_SLICE 12 +++#define RPI_TILESTART 16 +++#define RPI_TILEEND 20 +++#define RPI_SLICESTART 24 +++#define RPI_MODE 28 +++#define RPI_LEFT0 32 +++#define RPI_LEFT1 36 +++#define RPI_LEFT2 40 +++#define RPI_LEFT3 44 +++#define RPI_QP 48 +++#define RPI_CONTROL 52 +++#define RPI_STATUS 56 +++#define RPI_VERSION 60 +++#define RPI_BFBASE 64 +++#define RPI_BFNUM 68 +++#define RPI_BFCONTROL 72 +++#define RPI_BFSTATUS 76 +++#define RPI_PUWBASE 80 +++#define RPI_PUWSTRIDE 84 +++#define RPI_COEFFWBASE 88 +++#define RPI_COEFFWSTRIDE 92 +++#define RPI_SLICECMDS 96 +++#define RPI_BEGINTILEEND 100 +++#define RPI_TRANSFER 104 +++#define RPI_CFBASE 108 +++#define RPI_CFNUM 112 +++#define RPI_CFSTATUS 116 +++ +++#define RPI_PURBASE 0x8000 +++#define RPI_PURSTRIDE 0x8004 +++#define RPI_COEFFRBASE 0x8008 +++#define RPI_COEFFRSTRIDE 0x800C +++#define RPI_NUMROWS 0x8010 +++#define RPI_CONFIG2 0x8014 +++#define RPI_OUTYBASE 0x8018 +++#define RPI_OUTYSTRIDE 0x801C +++#define RPI_OUTCBASE 0x8020 +++#define RPI_OUTCSTRIDE 0x8024 +++#define RPI_STATUS2 0x8028 +++#define RPI_FRAMESIZE 0x802C +++#define RPI_MVBASE 0x8030 +++#define RPI_MVSTRIDE 0x8034 +++#define RPI_COLBASE 0x8038 +++#define RPI_COLSTRIDE 0x803C +++#define RPI_CURRPOC 0x8040 +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++struct FFM_PROB { +++ uint8_t sao_merge_flag [ 1]; +++ uint8_t sao_type_idx [ 1]; +++ uint8_t split_coding_unit_flag [ 3]; +++ uint8_t cu_transquant_bypass_flag [ 1]; +++ uint8_t skip_flag [ 3]; +++ uint8_t cu_qp_delta [ 3]; +++ uint8_t pred_mode_flag [ 1]; +++ uint8_t part_mode [ 4]; +++ uint8_t prev_intra_luma_pred_flag [ 1]; +++ uint8_t intra_chroma_pred_mode [ 2]; +++ uint8_t merge_flag [ 1]; +++ uint8_t merge_idx [ 1]; +++ uint8_t inter_pred_idc [ 5]; +++ uint8_t ref_idx_l0 [ 2]; +++ uint8_t ref_idx_l1 [ 2]; +++ uint8_t abs_mvd_greater0_flag [ 2]; +++ uint8_t abs_mvd_greater1_flag [ 2]; +++ uint8_t mvp_lx_flag [ 1]; +++ uint8_t no_residual_data_flag [ 1]; +++ uint8_t split_transform_flag [ 3]; +++ uint8_t cbf_luma [ 2]; +++ uint8_t cbf_cb_cr [ 4]; +++ uint8_t transform_skip_flag/*[][]*/ [ 2]; +++ uint8_t explicit_rdpcm_flag/*[][]*/ [ 2]; +++ uint8_t explicit_rdpcm_dir_flag/*[][]*/ [ 2]; +++ uint8_t last_significant_coeff_x_prefix [18]; +++ uint8_t last_significant_coeff_y_prefix [18]; +++ uint8_t significant_coeff_group_flag [ 4]; +++ uint8_t significant_coeff_flag [44]; +++ uint8_t coeff_abs_level_greater1_flag [24]; +++ uint8_t coeff_abs_level_greater2_flag [ 6]; +++ uint8_t log2_res_scale_abs [ 8]; +++ uint8_t res_scale_sign_flag [ 2]; +++ uint8_t cu_chroma_qp_offset_flag [ 1]; +++ uint8_t cu_chroma_qp_offset_idx [ 1]; +++} __attribute__((packed)); +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++struct RPI_PROB { +++ uint8_t SAO_MERGE_FLAG [ 1]; +++ uint8_t SAO_TYPE_IDX [ 1]; +++ uint8_t SPLIT_FLAG [ 3]; +++ uint8_t CU_SKIP_FLAG [ 3]; +++ uint8_t CU_TRANSQUANT_BYPASS_FLAG [ 1]; +++ uint8_t PRED_MODE [ 1]; +++ uint8_t PART_SIZE [ 4]; +++ uint8_t INTRA_PRED_MODE [ 1]; +++ uint8_t CHROMA_PRED_MODE [ 1]; +++ uint8_t MERGE_FLAG_EXT [ 1]; +++ uint8_t MERGE_IDX_EXT [ 1]; +++ uint8_t INTER_DIR [ 5]; +++ uint8_t REF_PIC [ 2]; +++ uint8_t MVP_IDX [ 1]; +++ uint8_t MVD [ 2]; +++ uint8_t QT_ROOT_CBF [ 1]; +++ uint8_t TRANS_SUBDIV_FLAG [ 3]; +++ uint8_t QT_CBF [ 6]; +++ uint8_t DQP [ 2]; +++ uint8_t ONE_FLAG [24]; +++ uint8_t LASTX [18]; +++ uint8_t LASTY [18]; +++ uint8_t SIG_CG_FLAG [ 4]; +++ uint8_t ABS_FLAG [ 6]; +++ uint8_t TRANSFORMSKIP_FLAG [ 2]; +++ uint8_t SIG_FLAG [42]; +++ uint8_t SIG_FLAG_unused [ 2]; +++} __attribute__((packed)); +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++struct RPI_CMD { +++ uint32_t addr; +++ uint32_t data; +++} __attribute__((packed)); +++ +++struct RPI_BIT { +++ int cmd; +++ const void *ptr; +++ int len; +++}; +++ +++////////////////////////////////////////////////////////////////////////////// +++ +++typedef struct RPI_T { +++struct RPI_BIT *bit_fifo; +++struct RPI_CMD *cmd_fifo; +++ int bit_len, bit_max; +++ int cmd_len, cmd_max; +++ int max_pu_msgs; +++ int max_coeff64; +++AVCodecContext *thread_avctx[MAX_THREADS]; +++ int thread_order[MAX_THREADS]; +++ int decode_order; +++ int phase1_order; +++ int phase2_order; +++pthread_mutex_t mutex_phase1; +++pthread_mutex_t mutex_phase2; +++ uint8_t scaling_factors[NUM_SCALING_FACTORS]; +++struct RPI_PROB probabilities; +++ int num_slice_msgs; +++ uint16_t slice_msgs[2*HEVC_MAX_REFS*8+3]; +++ int pubase64[MAX_THREADS]; +++ int pustep64; +++ int coeffbase64[MAX_THREADS]; +++ int coeffstep64; +++ int PicWidthInCtbsY; +++ int PicHeightInCtbsY; +++#ifdef AXI_BUFFERS +++ int lumabytes64; +++ int framebytes64; +++ int lumastride64; +++ int chromastride64; +++#endif +++ int mvframebytes64; +++ int mvstorage64; +++ int colstride64; +++ int mvstride64; +++ int colbase64[MAX_THREADS]; +++ int mvbase64[MAX_THREADS]; +++ uint32_t reg_slicestart; +++ int collocated_from_l0_flag; +++ int max_num_merge_cand; +++ int RefPicList[2][HEVC_MAX_REFS]; +++ int collocated_ref_idx; +++ int wpp_entry_x; +++ int wpp_entry_y; +++ +++ void * dl_handle; +++ void * id; +++ char * (* ctrl_ffmpeg_init) (const char *hwaccel_device, void **id); +++ void (* apb_write) (void *id, uint16_t addr, uint32_t data); +++ void (* apb_write_addr) (void *id, uint16_t addr, uint32_t data); +++ uint32_t (* apb_read) (void *id, uint16_t addr); +++ void (* apb_read_drop) (void *id, uint16_t addr); +++ void (* axi_write) (void *id, uint64_t addr, uint32_t size, const void *buf); +++ void (* axi_read_alloc) (void *id, uint32_t size); +++ void (* axi_read_tx) (void *id, uint64_t addr, uint32_t size); +++ void (* axi_read_rx) (void *id, uint32_t size, void *buf); +++ uint64_t (* axi_get_addr) (void *id); +++ void (* apb_dump_regs) (void *id, uint16_t addr, int num); +++ void (* axi_dump) (void *id, uint64_t addr, uint32_t size); +++ void (* axi_flush) (void *id, int mode); +++ void (* wait_interrupt) (void *id, int phase); +++ void (* ctrl_ffmpeg_free) (void *id); +++ +++} RPI_T; ++diff --git a/libavcodec/rpi_mailbox.c b/libavcodec/rpi_mailbox.c ++new file mode 100644 ++index 0000000000..5f23e9b36c ++--- /dev/null +++++ b/libavcodec/rpi_mailbox.c ++@@ -0,0 +1,149 @@ +++/* +++Copyright (c) 2012, Broadcom Europe Ltd. +++All rights reserved. +++ +++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. +++ * Redistributions in binary form must reproduce the above copyright +++ notice, this list of conditions and the following disclaimer in the +++ documentation and/or other materials provided with the distribution. +++ * Neither the name of the copyright holder nor the +++ names of its contributors may be used to endorse or promote products +++ derived from this software without specific prior written permission. +++ +++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 HOLDER 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. +++*/ +++ +++#if 1//defined(RPI) || defined (RPI_DISPLAY) +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#include +++ +++#define MAJOR_NUM 100 +++#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) +++#define DEVICE_FILE_NAME "/dev/vcio" +++ +++#include "rpi_mailbox.h" +++//#include +++ +++/* +++ * use ioctl to send mbox property message +++ */ +++ +++static int mbox_property(int file_desc, void *buf) +++{ +++ int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf); +++ +++ if (ret_val < 0) { +++ printf("ioctl_set_msg failed:%d\n", ret_val); +++ } +++ +++#ifdef DEBUG +++ unsigned *p = buf; int i; unsigned size = *(unsigned *)buf; +++ for (i=0; i +++#include +++#include +++#include +++#include +++#include "libavutil/avassert.h" +++ +++#include "config.h" +++ +++#include +++#include +++ +++#include +++ +++#include "rpi_mailbox.h" +++#include "rpi_qpu.h" +++ +++#pragma GCC diagnostic push +++// Many many redundant decls in the header files +++#pragma GCC diagnostic ignored "-Wredundant-decls" +++#include "interface/vmcs_host/vc_vchi_gpuserv.h" +++#pragma GCC diagnostic pop +++ +++// QPU "noflush" flags +++// a mixture of flushing & profiling +++ +++#define QPU_FLAGS_NO_FLUSH_VPU 1 // If unset VPU cache will be flushed +++#define QPU_FLAGS_PROF_CLEAR_AND_ENABLE 2 // Clear & Enable detailed QPU profiling registers +++#define QPU_FLAGS_PROF_OUTPUT_COUNTS 4 // Print the results +++#define QPU_FLAGS_OUTPUT_QPU_TIMES 8 // Print QPU times - independant of the profiling +++#define QPU_FLAGS_NO_FLUSH_QPU 16 // If unset flush QPU caches & TMUs (uniforms always flushed) +++ +++#define vcos_verify_ge0(x) ((x)>=0) +++ +++struct rpi_cache_flush_env_s { +++// unsigned int n; +++// struct vcsm_user_clean_invalid_s a[CFE_A_COUNT]; +++ struct vcsm_user_clean_invalid2_s v; +++}; +++ +++typedef struct gpu_env_s +++{ +++ int open_count; +++ int init_count; +++ int mb; +++ int vpu_i_cache_flushed; +++} gpu_env_t; +++ +++// Stop more than one thread trying to allocate memory or use the processing resources at once +++static pthread_mutex_t gpu_mutex = PTHREAD_MUTEX_INITIALIZER; +++static gpu_env_t * gpu = NULL; +++ +++ +++// GPU memory alloc fns (internal) +++ +++// GPU_MEM_PTR_T alloc fns +++static int gpu_malloc_cached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { +++ p->numbytes = (numbytes + 255) & ~255; // Round up +++ p->vcsm_handle = vcsm_malloc_cache(p->numbytes, VCSM_CACHE_TYPE_HOST | 0x80, (char *)"Video Frame" ); +++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_VC, (char *)"Video Frame" ); +++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE, (char *)"Video Frame" ); +++ //p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_HOST_AND_VC, (char *)"Video Frame" ); +++ av_assert0(p->vcsm_handle); +++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); +++ av_assert0(p->vc_handle); +++ p->arm = vcsm_lock(p->vcsm_handle); +++ av_assert0(p->arm); +++ p->vc = mbox_mem_lock(mb, p->vc_handle); +++ av_assert0(p->vc); +++// printf("***** %s, %d\n", __func__, numbytes); +++ +++ return 0; +++} +++ +++static int gpu_malloc_uncached_internal(const int mb, const int numbytes, GPU_MEM_PTR_T * const p) { +++ p->numbytes = numbytes; +++ p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE | 0x80, (char *)"Video Frame" ); +++ av_assert0(p->vcsm_handle); +++ p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle); +++ av_assert0(p->vc_handle); +++ p->arm = vcsm_lock(p->vcsm_handle); +++ av_assert0(p->arm); +++ p->vc = mbox_mem_lock(mb, p->vc_handle); +++ av_assert0(p->vc); +++// printf("***** %s, %d\n", __func__, numbytes); +++ return 0; +++} +++ +++static void gpu_free_internal(const int mb, GPU_MEM_PTR_T * const p) { +++ mbox_mem_unlock(mb, p->vc_handle); +++ vcsm_unlock_ptr(p->arm); +++ vcsm_free(p->vcsm_handle); +++ memset(p, 0, sizeof(*p)); // Ensure we crash hard if we try and use this again +++// printf("***** %s\n", __func__); +++} +++ +++ +++// GPU init, free, lock, unlock +++ +++static void gpu_term(void) +++{ +++ gpu_env_t * const ge = gpu; +++ +++ // We have to hope that eveything has terminated... +++ gpu = NULL; +++ +++ vc_gpuserv_deinit(); +++ +++ vcsm_exit(); +++ +++ mbox_close(ge->mb); +++ +++ free(ge); +++} +++ +++ +++// Connect to QPU, returns 0 on success. +++static int gpu_init(gpu_env_t ** const gpu) { +++ gpu_env_t * const ge = calloc(1, sizeof(gpu_env_t)); +++ *gpu = NULL; +++ +++ if (ge == NULL) +++ return -1; +++ +++ if ((ge->mb = mbox_open()) < 0) +++ return -1; +++ +++ vcsm_init(); +++ +++ *gpu = ge; +++ return 0; +++} +++ +++ +++ +++static void gpu_unlock(void) { +++ pthread_mutex_unlock(&gpu_mutex); +++} +++ +++// Make sure we have exclusive access to the mailbox, and enable qpu if necessary. +++static gpu_env_t * gpu_lock(void) { +++ pthread_mutex_lock(&gpu_mutex); +++ +++ av_assert0(gpu != NULL); +++ return gpu; +++} +++ +++static gpu_env_t * gpu_lock_ref(void) +++{ +++ pthread_mutex_lock(&gpu_mutex); +++ +++ if (gpu == NULL) { +++ int rv = gpu_init(&gpu); +++ if (rv != 0) { +++ gpu_unlock(); +++ return NULL; +++ } +++ } +++ +++ ++gpu->open_count; +++ return gpu; +++} +++ +++static void gpu_unlock_unref(gpu_env_t * const ge) +++{ +++ if (--ge->open_count == 0) +++ gpu_term(); +++ +++ gpu_unlock(); +++} +++ +++static inline gpu_env_t * gpu_ptr(void) +++{ +++ av_assert0(gpu != NULL); +++ return gpu; +++} +++ +++// Public gpu fns +++ +++// Allocate memory on GPU +++// Fills in structure

containing ARM pointer, videocore handle, videocore memory address, numbytes +++// Returns 0 on success. +++// This allocates memory that will not be cached in ARM's data cache. +++// Therefore safe to use without data cache flushing. +++int gpu_malloc_uncached(int numbytes, GPU_MEM_PTR_T *p) +++{ +++ int r; +++ gpu_env_t * const ge = gpu_lock_ref(); +++ if (ge == NULL) +++ return -1; +++ r = gpu_malloc_uncached_internal(ge->mb, numbytes, p); +++ gpu_unlock(); +++ return r; +++} +++ +++// This allocates data that will be +++// Cached in ARM L2 +++// Uncached in VPU L2 +++int gpu_malloc_cached(int numbytes, GPU_MEM_PTR_T *p) +++{ +++ int r; +++ gpu_env_t * const ge = gpu_lock_ref(); +++ if (ge == NULL) +++ return -1; +++ r = gpu_malloc_cached_internal(ge->mb, numbytes, p); +++ gpu_unlock(); +++ return r; +++} +++ +++void gpu_free(GPU_MEM_PTR_T * const p) { +++ gpu_env_t * const ge = gpu_lock(); +++ gpu_free_internal(ge->mb, p); +++ gpu_unlock_unref(ge); +++} +++ +++int gpu_get_mailbox(void) +++{ +++ av_assert0(gpu); +++ return gpu->mb; +++} +++ +++void gpu_ref(void) +++{ +++ gpu_lock_ref(); +++ gpu_unlock(); +++} +++ +++void gpu_unref(void) +++{ +++ gpu_env_t * const ge = gpu_lock(); +++ gpu_unlock_unref(ge); +++} +++ +++// ---------------------------------------------------------------------------- +++// +++// Cache flush functions +++ +++#define CACHE_EL_MAX 16 +++ +++rpi_cache_flush_env_t * rpi_cache_flush_init() +++{ +++ rpi_cache_flush_env_t * const rfe = malloc(sizeof(rpi_cache_flush_env_t) + +++ sizeof(struct vcsm_user_clean_invalid2_block_s) * CACHE_EL_MAX); +++ if (rfe == NULL) +++ return NULL; +++ +++ rfe->v.op_count = 0; +++ return rfe; +++} +++ +++void rpi_cache_flush_abort(rpi_cache_flush_env_t * const rfe) +++{ +++ if (rfe != NULL) +++ free(rfe); +++} +++ +++int rpi_cache_flush_finish(rpi_cache_flush_env_t * const rfe) +++{ +++ int rc = 0; +++ +++ if (vcsm_clean_invalid2(&rfe->v) != 0) +++ rc = -1; +++ +++ free(rfe); +++ +++ if (rc == 0) +++ return 0; +++ +++ av_log(NULL, AV_LOG_ERROR, "vcsm_clean_invalid failed: errno=%d\n", errno); +++ return rc; +++} +++ +++inline void rpi_cache_flush_add_gm_blocks(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, +++ const unsigned int offset0, const unsigned int block_size, const unsigned int blocks, const unsigned int block_stride) +++{ +++ struct vcsm_user_clean_invalid2_block_s * const b = rfe->v.s + rfe->v.op_count++; +++ +++ av_assert0(rfe->v.op_count <= CACHE_EL_MAX); +++ +++ b->invalidate_mode = mode; +++ b->block_count = blocks; +++ b->start_address = gm->arm + offset0; +++ b->block_size = block_size; +++ b->inter_block_stride = block_stride; +++} +++ +++void rpi_cache_flush_add_gm_range(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, +++ const unsigned int offset, const unsigned int size) +++{ +++ // Deal with empty pointer trivially +++ if (gm == NULL || size == 0) +++ return; +++ +++ av_assert0(offset <= gm->numbytes); +++ av_assert0(size <= gm->numbytes); +++ av_assert0(offset + size <= gm->numbytes); +++ +++ rpi_cache_flush_add_gm_blocks(rfe, gm, mode, offset, size, 1, 0); +++} +++ +++void rpi_cache_flush_add_gm_ptr(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode) +++{ +++ rpi_cache_flush_add_gm_blocks(rfe, gm, mode, 0, gm->numbytes, 1, 0); +++} +++ +++ +++void rpi_cache_flush_add_frame(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const unsigned int mode) +++{ +++#if !RPI_ONE_BUF +++#error Fixme! (NIF) +++#endif +++ if (gpu_is_buf1(frame)) { +++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf1_gmem(frame), mode); +++ } +++ else +++ { +++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 0), mode); +++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 1), mode); +++ rpi_cache_flush_add_gm_ptr(rfe, gpu_buf3_gmem(frame, 2), mode); +++ } +++} +++ +++// Call this to clean and invalidate a region of memory +++void rpi_cache_flush_one_gm_ptr(const GPU_MEM_PTR_T *const p, const rpi_cache_flush_mode_t mode) +++{ +++ rpi_cache_flush_env_t * rfe = rpi_cache_flush_init(); +++ rpi_cache_flush_add_gm_ptr(rfe, p, mode); +++ rpi_cache_flush_finish(rfe); +++} +++ +++ +++// ---------------------------------------------------------------------------- +++ +++#endif // RPI ++diff --git a/libavcodec/rpi_qpu.h b/libavcodec/rpi_qpu.h ++new file mode 100644 ++index 0000000000..485a08f8ba ++--- /dev/null +++++ b/libavcodec/rpi_qpu.h ++@@ -0,0 +1,206 @@ +++#ifndef RPI_QPU_H +++#define RPI_QPU_H +++ +++#define RPI_ONE_BUF 1 +++ +++typedef struct gpu_mem_ptr_s { +++ unsigned char *arm; // Pointer to memory mapped on ARM side +++ int vc_handle; // Videocore handle of relocatable memory +++ int vcsm_handle; // Handle for use by VCSM +++ int vc; // Address for use in GPU code +++ int numbytes; // Size of memory block +++} GPU_MEM_PTR_T; +++ +++// General GPU functions +++extern int gpu_malloc_cached(int numbytes, GPU_MEM_PTR_T *p); +++extern int gpu_malloc_uncached(int numbytes, GPU_MEM_PTR_T *p); +++extern void gpu_free(GPU_MEM_PTR_T * const p); +++ +++#include "libavutil/frame.h" +++#if !RPI_ONE_BUF +++static inline uint32_t get_vc_address_y(const AVFrame * const frame) { +++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[0]); +++ return p->vc; +++} +++ +++static inline uint32_t get_vc_address_u(const AVFrame * const frame) { +++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[1]); +++ return p->vc; +++} +++ +++static inline uint32_t get_vc_address_v(const AVFrame * const frame) { +++ GPU_MEM_PTR_T *p = av_buffer_pool_opaque(frame->buf[2]); +++ return p->vc; +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_y(const AVFrame * const frame) { +++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[0]); +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_u(const AVFrame * const frame) { +++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[1]); +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_v(const AVFrame * const frame) { +++ return *(GPU_MEM_PTR_T *)av_buffer_pool_opaque(frame->buf[2]); +++} +++ +++#else +++ +++static inline int gpu_is_buf1(const AVFrame * const frame) +++{ +++ return frame->buf[1] == NULL; +++} +++ +++static inline GPU_MEM_PTR_T * gpu_buf1_gmem(const AVFrame * const frame) +++{ +++ return av_buffer_get_opaque(frame->buf[0]); +++} +++ +++static inline GPU_MEM_PTR_T * gpu_buf3_gmem(const AVFrame * const frame, const unsigned int n) +++{ +++ return av_buffer_pool_opaque(frame->buf[n]); +++} +++ +++static inline uint32_t get_vc_address3(const AVFrame * const frame, const unsigned int n) +++{ +++ const GPU_MEM_PTR_T * const gm = gpu_is_buf1(frame) ? gpu_buf1_gmem(frame) : gpu_buf3_gmem(frame, n); +++ return gm->vc + (frame->data[n] - gm->arm); +++} +++ +++ +++static inline uint32_t get_vc_address_y(const AVFrame * const frame) { +++ return get_vc_address3(frame, 0); +++} +++ +++static inline uint32_t get_vc_address_u(const AVFrame * const frame) { +++ return get_vc_address3(frame, 1); +++} +++ +++static inline uint32_t get_vc_address_v(const AVFrame * const frame) { +++ return get_vc_address3(frame, 2); +++} +++ +++#if 0 +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_y(const AVFrame * const frame) { +++ if (gpu_is_buf1(frame)) +++ { +++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); +++ g.numbytes = frame->data[1] - frame->data[0]; +++ return g; +++ } +++ else +++ return *gpu_buf3_gmem(frame, 0); +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_u(const AVFrame * const frame) { +++ if (gpu_is_buf1(frame)) +++ { +++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); +++ g.arm += frame->data[1] - frame->data[0]; +++ g.vc += frame->data[1] - frame->data[0]; +++ g.numbytes = frame->data[2] - frame->data[1]; // chroma size +++ return g; +++ } +++ else +++ return *gpu_buf3_gmem(frame, 1); +++} +++ +++static inline GPU_MEM_PTR_T get_gpu_mem_ptr_v(const AVFrame * const frame) { +++ if (gpu_is_buf1(frame)) +++ { +++ GPU_MEM_PTR_T g = *gpu_buf1_gmem(frame); +++ g.arm += frame->data[2] - frame->data[0]; +++ g.vc += frame->data[2] - frame->data[0]; +++ g.numbytes = frame->data[2] - frame->data[1]; // chroma size +++ return g; +++ } +++ else +++ return *gpu_buf3_gmem(frame, 2); +++} +++#endif +++#endif +++ +++// Cache flush stuff +++ +++struct rpi_cache_flush_env_s; +++typedef struct rpi_cache_flush_env_s rpi_cache_flush_env_t; +++ +++rpi_cache_flush_env_t * rpi_cache_flush_init(void); +++// Free env without flushing +++void rpi_cache_flush_abort(rpi_cache_flush_env_t * const rfe); +++// Do the accumulated flush & free the env +++int rpi_cache_flush_finish(rpi_cache_flush_env_t * const rfe); +++ +++typedef enum +++{ +++ RPI_CACHE_FLUSH_MODE_INVALIDATE = 1, +++ RPI_CACHE_FLUSH_MODE_WRITEBACK = 2, +++ RPI_CACHE_FLUSH_MODE_WB_INVALIDATE = 3 +++} rpi_cache_flush_mode_t; +++ +++void rpi_cache_flush_add_gm_ptr(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const rpi_cache_flush_mode_t mode); +++void rpi_cache_flush_add_gm_range(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const rpi_cache_flush_mode_t mode, +++ const unsigned int offset, const unsigned int size); +++void rpi_cache_flush_add_gm_blocks(rpi_cache_flush_env_t * const rfe, const GPU_MEM_PTR_T * const gm, const unsigned int mode, +++ const unsigned int offset0, const unsigned int block_size, const unsigned int blocks, const unsigned int block_stride); +++void rpi_cache_flush_add_frame(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const rpi_cache_flush_mode_t mode); +++void rpi_cache_flush_add_frame_block(rpi_cache_flush_env_t * const rfe, const AVFrame * const frame, const rpi_cache_flush_mode_t mode, +++ const unsigned int x0, const unsigned int y0, const unsigned int width, const unsigned int height, +++ const unsigned int uv_shift, const int do_luma, const int do_chroma); +++ +++// init, add, finish for one gm ptr +++void rpi_cache_flush_one_gm_ptr(const GPU_MEM_PTR_T * const p, const rpi_cache_flush_mode_t mode); +++ +++ +++// QPU specific functions +++ +++typedef struct HEVCRpiQpu { +++ uint32_t c_pxx; +++ uint32_t c_pxx_l1; +++ uint32_t c_bxx; +++ uint32_t y_pxx; +++ uint32_t y_bxx; +++ uint32_t y_p00; +++ uint32_t y_b00; +++} HEVCRpiQpu; +++ +++int rpi_hevc_qpu_init_fn(HEVCRpiQpu * const qf, const unsigned int bit_depth); +++ +++uint32_t qpu_fn(const int * const mc_fn); +++ +++#define QPU_N_GRP 4 +++#define QPU_N_MAX 12 +++ +++#define QPU_MAIL_EL_VALS 2 +++ +++struct vpu_qpu_wait_s; +++typedef struct vq_wait_s * vpu_qpu_wait_h; +++ +++// VPU specific functions +++ +++struct vpu_qpu_job_env_s; +++typedef struct vpu_qpu_job_env_s * vpu_qpu_job_h; +++ +++vpu_qpu_job_h vpu_qpu_job_new(void); +++void vpu_qpu_job_delete(const vpu_qpu_job_h vqj); +++void vpu_qpu_job_add_vpu(const vpu_qpu_job_h vqj, const uint32_t vpu_code, +++ const unsigned r0, const unsigned r1, const unsigned r2, const unsigned r3, const unsigned r4, const unsigned r5); +++void vpu_qpu_job_add_qpu(const vpu_qpu_job_h vqj, const unsigned int n, const uint32_t * const mail); +++void vpu_qpu_job_add_sync_this(const vpu_qpu_job_h vqj, vpu_qpu_wait_h * const wait_h); +++int vpu_qpu_job_start(const vpu_qpu_job_h vqj); +++int vpu_qpu_job_finish(const vpu_qpu_job_h vqj); +++ +++extern unsigned int vpu_get_fn(const unsigned int bit_depth); +++extern unsigned int vpu_get_constants(void); +++ +++// Waits for previous post_codee to complete and Will null out *wait_h after use +++void vpu_qpu_wait(vpu_qpu_wait_h * const wait_h); +++int vpu_qpu_init(void); +++void vpu_qpu_term(void); +++ +++extern int gpu_get_mailbox(void); +++void gpu_ref(void); +++void gpu_unref(void); +++ +++#endif ++diff --git a/libavcodec/rpi_zc.c b/libavcodec/rpi_zc.c ++new file mode 100644 ++index 0000000000..3bf1da4083 ++--- /dev/null +++++ b/libavcodec/rpi_zc.c ++@@ -0,0 +1,743 @@ +++#include "config.h" +++#if 1 //defined(RPI) //|| defined (RPI_DISPLAY) +++#include "libavcodec/avcodec.h" +++#include "rpi_qpu.h" +++#include "rpi_mailbox.h" +++#include "rpi_zc.h" +++#include "libavutil/avassert.h" +++#include +++ +++#include "libavutil/buffer_internal.h" +++#include +++ +++#define TRACE_ALLOC 0 +++ +++struct ZcPoolEnt; +++ +++typedef struct ZcPool +++{ +++ int numbytes; +++ unsigned int n; +++ struct ZcPoolEnt * head; +++ pthread_mutex_t lock; +++} ZcPool; +++ +++typedef struct ZcPoolEnt +++{ +++ // It is important that we start with gmem as other bits of code will expect to see that +++ GPU_MEM_PTR_T gmem; +++ unsigned int n; +++ struct ZcPoolEnt * next; +++ struct ZcPool * pool; +++} ZcPoolEnt; +++ +++#define ALLOC_PAD 0 +++#define ALLOC_ROUND 0x1000 +++#define ALLOC_N_OFFSET 0 +++#define STRIDE_ROUND 64 +++#define STRIDE_OR 0 +++ +++#define DEBUG_ZAP0_BUFFERS 0 +++ +++static inline int av_rpi_is_sand_format(const int format) +++{ +++ return (format >= AV_PIX_FMT_SAND128 && format <= AV_PIX_FMT_SAND64_16) || +++ (format == AV_PIX_FMT_RPI4_8 || format == AV_PIX_FMT_RPI4_10); +++} +++ +++static inline int av_rpi_is_sand_frame(const AVFrame * const frame) +++{ +++ return av_rpi_is_sand_format(frame->format); +++} +++ +++static ZcPoolEnt * zc_pool_ent_alloc(ZcPool * const pool, const unsigned int req_size) +++{ +++ ZcPoolEnt * const zp = av_malloc(sizeof(ZcPoolEnt)); +++ +++ // Round up to 4k & add 4k +++ const unsigned int alloc_size = (req_size + ALLOC_PAD + ALLOC_ROUND - 1) & ~(ALLOC_ROUND - 1); +++ +++ if (zp == NULL) { +++ av_log(NULL, AV_LOG_ERROR, "av_malloc(ZcPoolEnt) failed\n"); +++ goto fail0; +++ } +++ +++ if (gpu_malloc_cached(alloc_size, &zp->gmem) != 0) +++ { +++ av_log(NULL, AV_LOG_ERROR, "av_gpu_malloc_cached(%d) failed\n", alloc_size); +++ goto fail1; +++ } +++ +++#if TRACE_ALLOC +++ printf("%s: Alloc %#x bytes @ %p\n", __func__, zp->gmem.numbytes, zp->gmem.arm); +++#endif +++ +++ pool->numbytes = zp->gmem.numbytes; +++ zp->next = NULL; +++ zp->pool = pool; +++ zp->n = pool->n++; +++ return zp; +++ +++fail1: +++ av_free(zp); +++fail0: +++ return NULL; +++} +++ +++static void zc_pool_ent_free(ZcPoolEnt * const zp) +++{ +++#if TRACE_ALLOC +++ printf("%s: Free %#x bytes @ %p\n", __func__, zp->gmem.numbytes, zp->gmem.arm); +++#endif +++ +++ gpu_free(&zp->gmem); +++ av_free(zp); +++} +++ +++static void zc_pool_flush(ZcPool * const pool) +++{ +++ ZcPoolEnt * p = pool->head; +++ pool->head = NULL; +++ pool->numbytes = -1; +++ +++ while (p != NULL) +++ { +++ ZcPoolEnt * const zp = p; +++ p = p->next; +++ zc_pool_ent_free(zp); +++ } +++} +++ +++static ZcPoolEnt * zc_pool_alloc(ZcPool * const pool, const int req_bytes) +++{ +++ ZcPoolEnt * zp; +++ int numbytes; +++ +++ pthread_mutex_lock(&pool->lock); +++ +++ numbytes = pool->numbytes; +++ +++ // If size isn't close then dump the pool +++ // Close in this context means within 128k +++ if (req_bytes > numbytes || req_bytes + 0x20000 < numbytes) +++ { +++ zc_pool_flush(pool); +++ numbytes = req_bytes; +++ } +++ +++ if (pool->head != NULL) +++ { +++ zp = pool->head; +++ pool->head = zp->next; +++ } +++ else +++ { +++ zp = zc_pool_ent_alloc(pool, numbytes); +++ } +++ +++ pthread_mutex_unlock(&pool->lock); +++ +++ // Start with our buffer empty of preconceptions +++// rpi_cache_flush_one_gm_ptr(&zp->gmem, RPI_CACHE_FLUSH_MODE_INVALIDATE); +++ +++ return zp; +++} +++ +++static void zc_pool_free(ZcPoolEnt * const zp) +++{ +++ ZcPool * const pool = zp == NULL ? NULL : zp->pool; +++ if (zp != NULL) +++ { +++ pthread_mutex_lock(&pool->lock); +++#if TRACE_ALLOC +++ printf("%s: Recycle %#x, %#x\n", __func__, pool->numbytes, zp->gmem.numbytes); +++#endif +++ +++ if (pool->numbytes == zp->gmem.numbytes) +++ { +++ zp->next = pool->head; +++ pool->head = zp; +++ pthread_mutex_unlock(&pool->lock); +++ } +++ else +++ { +++ pthread_mutex_unlock(&pool->lock); +++ zc_pool_ent_free(zp); +++ } +++ } +++} +++ +++static void +++zc_pool_init(ZcPool * const pool) +++{ +++ pool->numbytes = -1; +++ pool->head = NULL; +++ pthread_mutex_init(&pool->lock, NULL); +++} +++ +++static void +++zc_pool_destroy(ZcPool * const pool) +++{ +++ pool->numbytes = -1; +++ zc_pool_flush(pool); +++ pthread_mutex_destroy(&pool->lock); +++} +++ +++typedef struct ZcOldCtxVals +++{ +++ int thread_safe_callbacks; +++ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); +++ void * get_buffer_context; +++} ZcOldCtxVals; +++ +++typedef struct AVZcEnv +++{ +++ unsigned int refcount; +++ ZcPool pool; +++ ZcOldCtxVals old; +++} ZcEnv; +++ +++// Callback when buffer unrefed to zero +++static void rpi_free_display_buffer(void *opaque, uint8_t *data) +++{ +++ ZcPoolEnt *const zp = opaque; +++// printf("%s: data=%p\n", __func__, data); +++ zc_pool_free(zp); +++} +++ +++static inline GPU_MEM_PTR_T * pic_gm_ptr(AVBufferRef * const buf) +++{ +++ // Kludge where we check the free fn to check this is really +++ // one of our buffers - can't think of a better way +++ return buf == NULL || buf->buffer->free != rpi_free_display_buffer ? NULL : +++ av_buffer_get_opaque(buf); +++} +++ +++AVRpiZcFrameGeometry av_rpi_zc_frame_geometry( +++ const int format, const unsigned int video_width, const unsigned int video_height) +++{ +++ AVRpiZcFrameGeometry geo; +++ +++ switch (format) +++ { +++ case AV_PIX_FMT_YUV420P: +++ geo.stride_y = ((video_width + 32 + STRIDE_ROUND - 1) & ~(STRIDE_ROUND - 1)) | STRIDE_OR; +++ geo.stride_c = geo.stride_y / 2; +++ geo.height_y = (video_height + 32 + 31) & ~31; +++ geo.height_c = geo.height_y / 2; +++ geo.planes_c = 2; +++ geo.stripes = 1; +++ geo.bytes_per_pel = 1; +++ geo.stripe_is_yc = 1; +++ break; +++ +++ case AV_PIX_FMT_YUV420P10: +++ geo.stride_y = ((video_width * 2 + 64 + STRIDE_ROUND - 1) & ~(STRIDE_ROUND - 1)) | STRIDE_OR; +++ geo.stride_c = geo.stride_y / 2; +++ geo.height_y = (video_height + 32 + 31) & ~31; +++ geo.height_c = geo.height_y / 2; +++ geo.planes_c = 2; +++ geo.stripes = 1; +++ geo.bytes_per_pel = 2; +++ geo.stripe_is_yc = 1; +++ break; +++ +++ case AV_PIX_FMT_SAND128: +++ case AV_PIX_FMT_RPI4_8: +++ { +++ const unsigned int stripe_w = 128; +++ +++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; +++ static VC_IMAGE_T img = {0}; +++ +++ // Given the overhead of calling the mailbox keep a stashed +++ // copy as we will almost certainly just want the same numbers again +++ // but that means we need a lock +++ pthread_mutex_lock(&sand_lock); +++ +++ if (img.width != video_width || img.height != video_height) +++ { +++ VC_IMAGE_T new_img = { +++ .type = VC_IMAGE_YUV_UV, +++ .width = video_width, +++ .height = video_height +++ }; +++ +++ gpu_ref(); +++ mbox_get_image_params(gpu_get_mailbox(), &new_img); +++ gpu_unref(); +++ img = new_img; +++ } +++ +++ geo.stride_y = stripe_w; +++ geo.stride_c = stripe_w; +++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; +++ geo.height_c = img.pitch / stripe_w - geo.height_y; +++ geo.stripe_is_yc = 1; +++ if (geo.height_y * stripe_w > img.pitch) +++ { +++ // "tall" sand - all C blocks now follow Y +++ geo.height_y = img.pitch / stripe_w; +++ geo.height_c = geo.height_y; +++ geo.stripe_is_yc = 0; +++ } +++ geo.planes_c = 1; +++ geo.stripes = (video_width + stripe_w - 1) / stripe_w; +++ geo.bytes_per_pel = 1; +++ +++ pthread_mutex_unlock(&sand_lock); +++#if 0 +++ printf("Req: %dx%d: stride=%d/%d, height=%d/%d, stripes=%d, img.pitch=%d\n", +++ video_width, video_height, +++ geo.stride_y, geo.stride_c, +++ geo.height_y, geo.height_c, +++ geo.stripes, img.pitch); +++#endif +++ av_assert0((int)geo.height_y > 0 && (int)geo.height_c > 0); +++ av_assert0(geo.height_y >= video_height && geo.height_c >= video_height / 2); +++ break; +++ } +++ +++ case AV_PIX_FMT_RPI4_10: +++ { +++ const unsigned int stripe_w = 128; // bytes +++ +++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; +++ static VC_IMAGE_T img = {0}; +++ +++ // Given the overhead of calling the mailbox keep a stashed +++ // copy as we will almost certainly just want the same numbers again +++ // but that means we need a lock +++ pthread_mutex_lock(&sand_lock); +++ +++ if (img.width != video_width || img.height != video_height) +++ { +++ VC_IMAGE_T new_img = { +++ .type = VC_IMAGE_YUV10COL, +++ .width = video_width, +++ .height = video_height +++ }; +++ +++ gpu_ref(); +++ mbox_get_image_params(gpu_get_mailbox(), &new_img); +++ gpu_unref(); +++ img = new_img; +++ } +++ +++ geo.stride_y = stripe_w; +++ geo.stride_c = stripe_w; +++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; +++ geo.height_c = img.pitch / stripe_w - geo.height_y; +++ geo.planes_c = 1; +++ geo.stripes = ((video_width * 4 + 2) / 3 + stripe_w - 1) / stripe_w; +++ geo.bytes_per_pel = 1; +++ geo.stripe_is_yc = 1; +++ +++ pthread_mutex_unlock(&sand_lock); +++ +++ av_assert0((int)geo.height_y > 0 && (int)geo.height_c > 0); +++ av_assert0(geo.height_y >= video_height && geo.height_c >= video_height / 2); +++ break; +++ } +++ +++ case AV_PIX_FMT_SAND64_16: +++ case AV_PIX_FMT_SAND64_10: +++ { +++ const unsigned int stripe_w = 128; // bytes +++ +++ static pthread_mutex_t sand_lock = PTHREAD_MUTEX_INITIALIZER; +++ static VC_IMAGE_T img = {0}; +++ +++ // Given the overhead of calling the mailbox keep a stashed +++ // copy as we will almost certainly just want the same numbers again +++ // but that means we need a lock +++ pthread_mutex_lock(&sand_lock); +++ +++ if (img.width != video_width || img.height != video_height) +++ { +++ VC_IMAGE_T new_img = { +++ .type = VC_IMAGE_YUV_UV_16, +++ .width = video_width, +++ .height = video_height +++ }; +++ +++ gpu_ref(); +++ mbox_get_image_params(gpu_get_mailbox(), &new_img); +++ gpu_unref(); +++ img = new_img; +++ } +++ +++ geo.stride_y = stripe_w; +++ geo.stride_c = stripe_w; +++ geo.height_y = ((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w; +++ geo.height_c = img.pitch / stripe_w - geo.height_y; +++ geo.planes_c = 1; +++ geo.stripes = (video_width * 2 + stripe_w - 1) / stripe_w; +++ geo.bytes_per_pel = 2; +++ geo.stripe_is_yc = 1; +++ +++ pthread_mutex_unlock(&sand_lock); +++ break; +++ } +++ +++ default: +++ memset(&geo, 0, sizeof(geo)); +++ break; +++ } +++ return geo; +++} +++ +++ +++static AVBufferRef * rpi_buf_pool_alloc(ZcPool * const pool, int size) +++{ +++ ZcPoolEnt *const zp = zc_pool_alloc(pool, size); +++ AVBufferRef * buf; +++ intptr_t idata = (intptr_t)zp->gmem.arm; +++#if ALLOC_N_OFFSET != 0 +++ intptr_t noff = (zp->n * ALLOC_N_OFFSET) & (ALLOC_PAD - 1); +++#endif +++ +++ if (zp == NULL) { +++ av_log(NULL, AV_LOG_ERROR, "zc_pool_alloc(%d) failed\n", size); +++ goto fail0; +++ } +++ +++#if ALLOC_N_OFFSET != 0 +++ idata = ((idata & ~(ALLOC_PAD - 1)) | noff) + (((idata & (ALLOC_PAD - 1)) > noff) ? ALLOC_PAD : 0); +++#endif +++ +++#if DEBUG_ZAP0_BUFFERS +++ memset((void*)idata, 0, size); +++#endif +++ +++ if ((buf = av_buffer_create((void *)idata, size, rpi_free_display_buffer, zp, AV_BUFFER_FLAG_READONLY)) == NULL) +++ { +++ av_log(NULL, AV_LOG_ERROR, "av_buffer_create() failed\n"); +++ goto fail2; +++ } +++ +++ return buf; +++ +++fail2: +++ zc_pool_free(zp); +++fail0: +++ return NULL; +++} +++ +++static int rpi_get_display_buffer(ZcEnv *const zc, AVFrame * const frame) +++{ +++ const AVRpiZcFrameGeometry geo = av_rpi_zc_frame_geometry(frame->format, frame->width, frame->height); +++ const unsigned int size_y = geo.stride_y * geo.height_y; +++ const unsigned int size_c = geo.stride_c * geo.height_c; +++ const unsigned int size_pic = (size_y + size_c * geo.planes_c) * geo.stripes; +++ AVBufferRef * buf; +++ unsigned int i; +++ +++// printf("Do local alloc: format=%#x, %dx%d: %u\n", frame->format, frame->width, frame->height, size_pic); +++ +++ if ((buf = rpi_buf_pool_alloc(&zc->pool, size_pic)) == NULL) +++ { +++ av_log(NULL, AV_LOG_ERROR, "rpi_get_display_buffer: Failed to get buffer from pool\n"); +++ return AVERROR(ENOMEM); +++ } +++ +++ for (i = 0; i < AV_NUM_DATA_POINTERS; i++) { +++ frame->buf[i] = NULL; +++ frame->data[i] = NULL; +++ frame->linesize[i] = 0; +++ } +++ +++ frame->buf[0] = buf; +++ +++ frame->linesize[0] = geo.stride_y; +++ frame->linesize[1] = geo.stride_c; +++ frame->linesize[2] = geo.stride_c; +++ // abuse: linesize[3] = "stripe stride" +++ // stripe_stride is NOT the stride between slices it is (that / geo.stride_y). +++ // In a general case this makes the calculation an xor and multiply rather +++ // than a divide and multiply +++ if (geo.stripes > 1) +++ frame->linesize[3] = geo.stripe_is_yc ? geo.height_y + geo.height_c : geo.height_y; +++ +++ frame->data[0] = buf->data; +++ frame->data[1] = frame->data[0] + (geo.stripe_is_yc ? size_y : size_y * geo.stripes); +++ if (geo.planes_c > 1) +++ frame->data[2] = frame->data[1] + size_c; +++ +++ frame->extended_data = frame->data; +++ // Leave extended buf alone +++ +++#if RPI_ZC_SAND_8_IN_10_BUF != 0 +++ // *** If we intend to use this for real we will want a 2nd buffer pool +++ frame->buf[RPI_ZC_SAND_8_IN_10_BUF] = rpi_buf_pool_alloc(&zc->pool, size_pic); // *** 2 * wanted size - kludge +++#endif +++ +++ return 0; +++} +++ +++#define RPI_GET_BUFFER2 1 +++ +++int av_rpi_zc_get_buffer2(struct AVCodecContext *s, AVFrame *frame, int flags) +++{ +++#if !RPI_GET_BUFFER2 +++ return avcodec_default_get_buffer2(s, frame, flags); +++#else +++ int rv; +++ +++ if ((s->codec->capabilities & AV_CODEC_CAP_DR1) == 0) +++ { +++// printf("Do default alloc: format=%#x\n", frame->format); +++ rv = avcodec_default_get_buffer2(s, frame, flags); +++ } +++ else if (frame->format == AV_PIX_FMT_YUV420P || +++ av_rpi_is_sand_frame(frame)) +++ { +++ rv = rpi_get_display_buffer(s->get_buffer_context, frame); +++ } +++ else +++ { +++ rv = avcodec_default_get_buffer2(s, frame, flags); +++ } +++ +++#if 0 +++ printf("%s: fmt:%d, %dx%d lsize=%d/%d/%d/%d data=%p/%p/%p bref=%p/%p/%p opaque[0]=%p\n", __func__, +++ frame->format, frame->width, frame->height, +++ frame->linesize[0], frame->linesize[1], frame->linesize[2], frame->linesize[3], +++ frame->data[0], frame->data[1], frame->data[2], +++ frame->buf[0], frame->buf[1], frame->buf[2], +++ av_buffer_get_opaque(frame->buf[0])); +++#endif +++ return rv; +++#endif +++} +++ +++ +++static AVBufferRef * zc_copy(struct AVCodecContext * const s, +++ const AVFrame * const src) +++{ +++ AVFrame dest_frame; +++ AVFrame * const dest = &dest_frame; +++ unsigned int i; +++ uint8_t * psrc, * pdest; +++ +++ dest->format = src->format; +++ dest->width = src->width; +++ dest->height = src->height; +++ +++ if (rpi_get_display_buffer(s->get_buffer_context, dest) != 0) +++ { +++ return NULL; +++ } +++ +++ for (i = 0, psrc = src->data[0], pdest = dest->data[0]; +++ i != dest->height; +++ ++i, psrc += src->linesize[0], pdest += dest->linesize[0]) +++ { +++ memcpy(pdest, psrc, dest->width); +++ } +++ for (i = 0, psrc = src->data[1], pdest = dest->data[1]; +++ i != dest->height / 2; +++ ++i, psrc += src->linesize[1], pdest += dest->linesize[1]) +++ { +++ memcpy(pdest, psrc, dest->width / 2); +++ } +++ for (i = 0, psrc = src->data[2], pdest = dest->data[2]; +++ i != dest->height / 2; +++ ++i, psrc += src->linesize[2], pdest += dest->linesize[2]) +++ { +++ memcpy(pdest, psrc, dest->width / 2); +++ } +++ +++ return dest->buf[0]; +++} +++ +++ +++static AVBufferRef * zc_420p10_to_sand128(struct AVCodecContext * const s, +++ const AVFrame * const src) +++{ +++ assert(0); +++ return NULL; +++} +++ +++ +++static AVBufferRef * zc_sand64_16_to_sand128(struct AVCodecContext * const s, +++ const AVFrame * const src, const unsigned int src_bits) +++{ +++ assert(0); +++ return NULL; +++} +++ +++ +++ +++AVRpiZcRefPtr av_rpi_zc_ref(struct AVCodecContext * const s, +++ const AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy) +++{ +++ assert(s != NULL); +++ +++ if (frame->format != AV_PIX_FMT_YUV420P && +++ frame->format != AV_PIX_FMT_YUV420P10 && +++ !av_rpi_is_sand_frame(frame)) +++ { +++ av_log(s, AV_LOG_WARNING, "%s: *** Format not SAND/YUV420P: %d\n", __func__, frame->format); +++ return NULL; +++ } +++ +++ if (frame->buf[1] != NULL || frame->format != expected_format) +++ { +++#if RPI_ZC_SAND_8_IN_10_BUF +++ if (frame->format == AV_PIX_FMT_SAND64_10 && expected_format == AV_PIX_FMT_SAND128 && frame->buf[RPI_ZC_SAND_8_IN_10_BUF] != NULL) +++ { +++// av_log(s, AV_LOG_INFO, "%s: --- found buf[4]\n", __func__); +++ return av_buffer_ref(frame->buf[RPI_ZC_SAND_8_IN_10_BUF]); +++ } +++#endif +++ +++ if (maycopy) +++ { +++ if (frame->buf[1] != NULL) +++ av_log(s, AV_LOG_INFO, "%s: *** Not a single buf frame: copying\n", __func__); +++ else +++ av_log(s, AV_LOG_INFO, "%s: *** Unexpected frame format %d: copying to %d\n", __func__, frame->format, expected_format); +++ +++ switch (frame->format) +++ { +++ case AV_PIX_FMT_YUV420P10: +++ return zc_420p10_to_sand128(s, frame); +++ +++ case AV_PIX_FMT_SAND64_10: +++ return zc_sand64_16_to_sand128(s, frame, 10); +++ +++ default: +++ return zc_copy(s, frame); +++ } +++ } +++ else +++ { +++ if (frame->buf[1] != NULL) +++ av_log(s, AV_LOG_WARNING, "%s: *** Not a single buf frame: buf[1] != NULL\n", __func__); +++ else +++ av_log(s, AV_LOG_INFO, "%s: *** Unexpected frame format: %d != %d\n", __func__, frame->format, expected_format); +++ return NULL; +++ } +++ } +++ +++ if (pic_gm_ptr(frame->buf[0]) == NULL) +++ { +++ if (maycopy) +++ { +++ av_log(s, AV_LOG_INFO, "%s: *** Not one of our buffers: copying\n", __func__); +++ return zc_copy(s, frame); +++ } +++ else +++ { +++ av_log(s, AV_LOG_WARNING, "%s: *** Not one of our buffers: NULL\n", __func__); +++ return NULL; +++ } +++ } +++ +++ return av_buffer_ref(frame->buf[0]); +++} +++ +++int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref) +++{ +++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); +++ return p == NULL ? -1 : p->vc_handle; +++} +++ +++int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref) +++{ +++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); +++ return p == NULL ? 0 : fr_ref->data - p->arm; +++} +++ +++int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref) +++{ +++ return fr_ref == NULL ? 0 : fr_ref->size; +++} +++ +++ +++int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref) +++{ +++ const GPU_MEM_PTR_T * const p = pic_gm_ptr(fr_ref); +++ return p == NULL ? 0 : p->numbytes; +++} +++ +++void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref) +++{ +++ if (fr_ref != NULL) +++ { +++ av_buffer_unref(&fr_ref); +++ } +++} +++ +++AVZcEnvPtr av_rpi_zc_env_alloc(void) +++{ +++ ZcEnv * const zc = av_mallocz(sizeof(ZcEnv)); +++ if (zc == NULL) +++ { +++ av_log(NULL, AV_LOG_ERROR, "av_rpi_zc_env_alloc: Context allocation failed\n"); +++ return NULL; +++ } +++ +++ zc_pool_init(&zc->pool); +++ return zc; +++} +++ +++void av_rpi_zc_env_free(AVZcEnvPtr zc) +++{ +++ if (zc != NULL) +++ { +++ zc_pool_destroy(&zc->pool); ; +++ av_free(zc); +++ } +++} +++ +++int av_rpi_zc_in_use(const struct AVCodecContext * const s) +++{ +++ return s->get_buffer2 == av_rpi_zc_get_buffer2; +++} +++ +++int av_rpi_zc_init(struct AVCodecContext * const s) +++{ +++ if (av_rpi_zc_in_use(s)) +++ { +++ ZcEnv * const zc = s->get_buffer_context; +++ ++zc->refcount; +++ } +++ else +++ { +++ ZcEnv *const zc = av_rpi_zc_env_alloc(); +++ if (zc == NULL) +++ { +++ return AVERROR(ENOMEM); +++ } +++ +++ zc->refcount = 1; +++ zc->old.get_buffer_context = s->get_buffer_context; +++ zc->old.get_buffer2 = s->get_buffer2; +++ zc->old.thread_safe_callbacks = s->thread_safe_callbacks; +++ +++ s->get_buffer_context = zc; +++ s->get_buffer2 = av_rpi_zc_get_buffer2; +++ s->thread_safe_callbacks = 1; +++ } +++ return 0; +++} +++ +++void av_rpi_zc_uninit(struct AVCodecContext * const s) +++{ +++ if (av_rpi_zc_in_use(s)) +++ { +++ ZcEnv * const zc = s->get_buffer_context; +++ if (--zc->refcount == 0) +++ { +++ s->get_buffer2 = zc->old.get_buffer2; +++ s->get_buffer_context = zc->old.get_buffer_context; +++ s->thread_safe_callbacks = zc->old.thread_safe_callbacks; +++ av_rpi_zc_env_free(zc); +++ } +++ } +++} +++ +++#endif // RPI +++ ++diff --git a/libavcodec/rpi_zc.h b/libavcodec/rpi_zc.h ++new file mode 100644 ++index 0000000000..0e39b8e3b3 ++--- /dev/null +++++ b/libavcodec/rpi_zc.h ++@@ -0,0 +1,106 @@ +++#ifndef LIBAVCODEC_RPI_ZC_H +++#define LIBAVCODEC_RPI_ZC_H +++ +++// Zero-Copy frame code for RPi +++// RPi needs Y/U/V planes to be contiguous for display. By default +++// ffmpeg will allocate separated planes so a memcpy is needed before +++// display. This code provides a method a making ffmpeg allocate a single +++// bit of memory for the frame when can then be reference counted until +++// display has finished with it. +++ +++// Frame buffer number in which to stuff an 8-bit copy of a 16-bit frame +++// 0 disables +++// *** This option still in development +++// Only works if SAO active +++// Allocates buffers that are twice the required size +++#define RPI_ZC_SAND_8_IN_10_BUF 0 +++ +++struct AVBufferRef; +++struct AVFrame; +++struct AVCodecContext; +++enum AVPixelFormat; +++ +++// "Opaque" pointer to whatever we are using as a buffer reference +++typedef struct AVBufferRef * AVRpiZcRefPtr; +++ +++struct AVZcEnv; +++typedef struct AVZcEnv * AVZcEnvPtr; +++ +++typedef struct AVRpiZcFrameGeometry +++{ +++ unsigned int stride_y; // Luma stride (bytes) +++ unsigned int height_y; // Luma height (lines) +++ unsigned int stride_c; // Chroma stride (bytes) +++ unsigned int height_c; // Chroma stride (lines) +++ unsigned int planes_c; // Chroma plane count (U, V = 2, interleaved = 1) +++ unsigned int stripes; // Number of stripes (sand) +++ unsigned int bytes_per_pel; +++ int stripe_is_yc; // A single stripe is Y then C (false for tall sand) +++} AVRpiZcFrameGeometry; +++ +++ +++AVRpiZcFrameGeometry av_rpi_zc_frame_geometry( +++ const int format, +++ const unsigned int video_width, const unsigned int video_height); +++ +++// Replacement fn for avctx->get_buffer2 +++// Should be set before calling avcodec_decode_open2 +++// +++// N.B. in addition to to setting avctx->get_buffer2, avctx->refcounted_frames +++// must be set to 1 as otherwise the buffer info is killed before being returned +++// by avcodec_decode_video2. Note also that this means that the AVFrame that is +++// returned must be manually derefed with av_frame_unref. This should be done +++// after av_rpi_zc_ref has been called. +++int av_rpi_zc_get_buffer2(struct AVCodecContext *s, AVFrame *frame, int flags); +++ +++// Generate a ZC reference to the buffer(s) in this frame +++// If the buffer doesn't appear to be one allocated by _get_buffer_2 +++// then the behaviour depends on maycopy: +++// If maycopy=0 then return NULL +++// If maycopy=1 && the src frame is in a form where we can easily copy +++// the data, then allocate a new buffer and copy the data into it +++// Otherwise return NULL +++AVRpiZcRefPtr av_rpi_zc_ref(struct AVCodecContext * const s, +++ const struct AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy); +++ +++// Get the vc_handle from the frame ref +++// Returns -1 if ref doesn't look valid +++int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref); +++// Get offset from the start of the memory referenced +++// by the vc_handle to valid data +++int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref); +++// Length of buffer data +++int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref); +++// Get the number of bytes allocated from the frame ref +++// Returns 0 if ref doesn't look valid +++int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref); +++ +++// Unreference the buffer refed/allocated by _zc_ref +++// If fr_ref is NULL then this will NOP +++void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref); +++ +++// Allocate an environment for the buffer pool used by the ZC code +++// This should be put in avctx->get_buffer_context so it can be found by +++// av_rpi_zc_get_buffer2 when it is called from ffmpeg +++AVZcEnvPtr av_rpi_zc_env_alloc(void); +++ +++// Allocate the environment used by the ZC code +++void av_rpi_zc_env_free(AVZcEnvPtr); +++ +++// Test to see if the context is using zc (checks get_buffer2) +++int av_rpi_zc_in_use(const struct AVCodecContext * const s); +++ +++// Init ZC into a context +++// There is nothing magic in this fn - it just packages setting +++// get_buffer2 & get_buffer_context +++int av_rpi_zc_init(struct AVCodecContext * const s); +++ +++// Free ZC from a context +++// There is nothing magic in this fn - it just packages unsetting +++// get_buffer2 & get_buffer_context +++void av_rpi_zc_uninit(struct AVCodecContext * const s); +++ +++ +++ +++#endif +++ ++diff --git a/libavutil/buffer.c b/libavutil/buffer.c ++index 8d1aa5fa84..649876db77 100644 ++--- a/libavutil/buffer.c +++++ b/libavutil/buffer.c ++@@ -355,3 +355,9 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) ++ ++ return ret; ++ } +++ +++// Return the opaque for the underlying frame (gives us a GPU_MEM_PTR_T) +++void *av_buffer_pool_opaque(AVBufferRef *ref) { +++ BufferPoolEntry *buf = av_buffer_get_opaque(ref); +++ return buf->opaque; +++} ++diff --git a/libavutil/buffer.h b/libavutil/buffer.h ++index 73b6bd0b14..d907de3f1c 100644 ++--- a/libavutil/buffer.h +++++ b/libavutil/buffer.h ++@@ -284,6 +284,9 @@ void av_buffer_pool_uninit(AVBufferPool **pool); ++ */ ++ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); ++ +++// Return the opaque for the underlying frame +++void *av_buffer_pool_opaque(AVBufferRef *ref); +++ ++ /** ++ * @} ++ */ ++diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c ++index 8ed52751c1..5e2b5ec3bc 100644 ++--- a/libavutil/pixdesc.c +++++ b/libavutil/pixdesc.c ++@@ -1989,6 +1989,18 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { ++ .name = "cuda", ++ .flags = AV_PIX_FMT_FLAG_HWACCEL, ++ }, +++ [AV_PIX_FMT_RPI] = { +++ .name = "rpi", +++ .flags = AV_PIX_FMT_FLAG_HWACCEL, +++ }, +++ [AV_PIX_FMT_RPI4_10] = { +++ .name = "rpi", +++ .flags = AV_PIX_FMT_FLAG_HWACCEL, +++ }, +++ [AV_PIX_FMT_RPI4_8] = { +++ .name = "rpi", +++ .flags = AV_PIX_FMT_FLAG_HWACCEL, +++ }, ++ [AV_PIX_FMT_AYUV64LE] = { ++ .name = "ayuv64le", ++ .nb_components = 4, ++diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h ++index 34a1531489..0a6ff1f482 100644 ++--- a/libavutil/pixfmt.h +++++ b/libavutil/pixfmt.h ++@@ -234,6 +234,11 @@ enum AVPixelFormat { ++ */ ++ AV_PIX_FMT_CUDA, ++ +++ /** +++ * HW acceleration through RPI. +++ */ +++ AV_PIX_FMT_RPI, +++ ++ AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined ++ AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined ++ AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined ++@@ -334,6 +339,14 @@ enum AVPixelFormat { ++ */ ++ AV_PIX_FMT_OPENCL, ++ +++// RPI - not on ifdef so can be got at by calling progs +++ AV_PIX_FMT_SAND128, ///< 4:2:0 8-bit 128x*Y stripe, 64x*UV stripe, then next x stripe, mysterious padding +++ AV_PIX_FMT_SAND64_10, ///< 4:2:0 10-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding +++ AV_PIX_FMT_SAND64_16, ///< 4:2:0 16-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding +++ +++ AV_PIX_FMT_RPI4_8, +++ AV_PIX_FMT_RPI4_10, +++ ++ AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions ++ }; ++ ++diff --git a/pi-util/conf_pi1.sh b/pi-util/conf_pi1.sh ++new file mode 100755 ++index 0000000000..ec25b81c31 ++--- /dev/null +++++ b/pi-util/conf_pi1.sh ++@@ -0,0 +1,31 @@ +++echo "Configure for Pi1" +++ +++RPI_TOOLROOT=`pwd`/../tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf +++RPI_OPT_VC=`pwd`/../firmware/opt/vc +++ +++RPI_INCLUDES="-I$RPI_OPT_VC/include -I$RPI_OPT_VC/include/interface/vcos/pthreads -I$RPI_OPT_VC/include/interface/vmcs_host/linux" +++RPI_DEFS="-D__VCCOREVER__=0x04000000 -DRPI=1" +++RPI_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib" +++#RPI_KEEPS="-save-temps=obj" +++RPI_KEEPS="" +++ +++./configure --enable-cross-compile\ +++ --cpu=arm1176jzf-s\ +++ --arch=arm\ +++ --disable-neon\ +++ --target-os=linux\ +++ --disable-stripping\ +++ --enable-mmal\ +++ --extra-cflags="-g $RPI_KEEPS $RPI_DEFS $RPI_INCLUDES"\ +++ --extra-cxxflags="$RPI_DEFS $RPI_INCLUDES"\ +++ --extra-ldflags="$RPI_LIBDIRS -Wl,-rpath=/opt/vc/lib,-rpath-link=$RPI_OPT_VC/lib,-rpath=/lib,-rpath=/usr/lib,-rpath-link=$RPI_TOOLROOT/lib,-rpath-link=$RPI_TOOLROOT/lib"\ +++ --extra-libs="-Wl,--start-group -lbcm_host -lmmal -lmmal_util -lmmal_core -lvcos -lvcsm -lvchostif -lvchiq_arm"\ +++ --cross-prefix=$RPI_TOOLROOT/bin/arm-linux-gnueabihf- +++ +++ +++# --enable-extra-warnings\ +++# --arch=armv71\ +++# --enable-shared\ +++ +++# gcc option for getting asm listing +++# -Wa,-ahls ++diff --git a/pi-util/conf_pi2.sh b/pi-util/conf_pi2.sh ++new file mode 100755 ++index 0000000000..7ec0402ce8 ++--- /dev/null +++++ b/pi-util/conf_pi2.sh ++@@ -0,0 +1,34 @@ +++echo "Configure for Pi2/3" +++ +++RPI_TOOLROOT=/home/dom/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf +++RPI_OPT_VC=/opt/bcm-rootfs/opt/vc +++ +++RPI_INCLUDES="-I$RPI_OPT_VC/include -I$RPI_OPT_VC/include/interface/vcos/pthreads -I$RPI_OPT_VC/include/interface/vmcs_host/linux" +++RPI_DEFS="-D__VCCOREVER__=0x04000000 -DRPI_DISPLAY=1" +++RPI_LIBDIRS="-L$RPI_TOOLROOT/lib -L$RPI_OPT_VC/lib" +++#RPI_KEEPS="-save-temps=obj" +++RPI_KEEPS="" +++ +++./configure --enable-cross-compile\ +++ --arch=armv6t2\ +++ --cpu=cortex-a7\ +++ --target-os=linux\ +++ --disable-stripping\ +++ --disable-thumb\ +++ --enable-mmal\ +++ --enable-rpi\ +++ --extra-cflags="-g $RPI_KEEPS $RPI_DEFS $RPI_INCLUDES"\ +++ --extra-cxxflags="$RPI_DEFS $RPI_INCLUDES"\ +++ --extra-ldflags="$RPI_LIBDIRS -Wl,-rpath=/opt/vc/lib,-rpath-link=$RPI_OPT_VC/lib,-rpath=/lib,-rpath=/usr/lib,-rpath-link=$RPI_TOOLROOT/lib,-rpath-link=$RPI_TOOLROOT/lib"\ +++ --extra-libs="-Wl,--start-group -lbcm_host -lmmal -lmmal_util -lmmal_core -lvcos -lvcsm -lvchostif -lvchiq_arm"\ +++ --cross-prefix=$RPI_TOOLROOT/bin/arm-linux-gnueabihf- \ +++ --prefix=$HOME/buster/home/pi/projects/fpga \ +++ --extra-libs="-ldl" +++ +++# --disable-decoders --enable-decoder=hevc --disable-hwaccels --enable-hwaccel=hevc_rpi --disable-encoders --enable-encoder=rawvideo --enable-muxer=rawvideo \ +++# --enable-extra-warnings\ +++# --arch=armv71\ +++# --enable-shared\ +++ +++# gcc option for getting asm listing +++# -Wa,-ahls +-- +2.20.1 + + +From b6633c36d3855a81d32dbf0dd68358267d0e7c2c Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 26 Jun 2017 20:17:09 +0100 +Subject: [PATCH 03/14] MMAL: Add hevc support by allowing 4 planes + +--- + xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp | 3 +++ + xbmc/cores/VideoPlayer/Process/VideoBuffer.h | 2 +- + .../VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp | 3 +++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +index 2cf3575ca9..854f34fa62 100644 +--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp ++++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +@@ -77,6 +77,8 @@ void CMMALYUVBuffer::GetStrides(int(&strides)[YuvImage::MAX_PLANES]) + strides[0] = geo.getStrideY(); + strides[1] = geo.getStrideC(); + strides[2] = geo.getStrideC(); ++ if (geo.getStripes() > 1) ++ strides[3] = geo.getHeightY() + geo.getHeightC(); // abuse: strides[3] = stripe stride + } + + void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) +@@ -284,6 +286,7 @@ CDVDVideoCodec::VCReturn CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) + if (frame) + { + if ((frame->format != AV_PIX_FMT_YUV420P && frame->format != AV_PIX_FMT_YUV420P10 && frame->format != AV_PIX_FMT_YUV420P12 && frame->format != AV_PIX_FMT_YUV420P14 && frame->format != AV_PIX_FMT_YUV420P16 && ++ frame->format != AV_PIX_FMT_SAND128 && frame->format != AV_PIX_FMT_SAND64_10 && frame->format != AV_PIX_FMT_SAND64_16 && + frame->format != AV_PIX_FMT_BGR0 && frame->format != AV_PIX_FMT_RGB565LE) || + frame->buf[1] != nullptr || frame->buf[0] == nullptr) + { +diff --git a/xbmc/cores/VideoPlayer/Process/VideoBuffer.h b/xbmc/cores/VideoPlayer/Process/VideoBuffer.h +index 1c1ba21c48..86a71bb558 100644 +--- a/xbmc/cores/VideoPlayer/Process/VideoBuffer.h ++++ b/xbmc/cores/VideoPlayer/Process/VideoBuffer.h +@@ -23,7 +23,7 @@ extern "C" { + + struct YuvImage + { +- static const int MAX_PLANES = 3; ++ static const int MAX_PLANES = 4; + + uint8_t* plane[MAX_PLANES]; + int planesize[MAX_PLANES]; +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +index aa5b0e06c0..fae5df73e2 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +@@ -193,6 +193,9 @@ std::vector CMMALPool::mmal_encoding_table = + { AV_PIX_FMT_YUV420P12,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P14,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P16,MMAL_ENCODING_I420_16, }, ++ { AV_PIX_FMT_SAND128, MMAL_ENCODING_YUVUV128 }, ++ { AV_PIX_FMT_SAND64_10,MMAL_ENCODING_YUVUV64_16 }, ++ { AV_PIX_FMT_SAND64_16,MMAL_ENCODING_YUVUV64_16 }, + { AV_PIX_FMT_RGBA, MMAL_ENCODING_RGBA, }, + { AV_PIX_FMT_BGRA, MMAL_ENCODING_BGRA }, + { AV_PIX_FMT_RGB0, MMAL_ENCODING_RGBA }, +-- +2.20.1 + + +From 0f8645a751d04e657a82a66d42a0c56205097466 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 17 May 2019 18:52:34 +0100 +Subject: [PATCH 04/14] RPI: Apply ffmpeg patches through cmake + +--- + cmake/modules/FindFFMPEG.cmake | 5 ++++- + tools/depends/target/ffmpeg/CMakeLists.txt | 5 +++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake +index ef74671d40..a6e5de5917 100644 +--- a/cmake/modules/FindFFMPEG.cmake ++++ b/cmake/modules/FindFFMPEG.cmake +@@ -270,7 +270,10 @@ if(NOT FFMPEG_FOUND) + && + ${CMAKE_COMMAND} -E copy + ${CMAKE_SOURCE_DIR}/tools/depends/target/ffmpeg/FindGnuTls.cmake +- ) ++ && ++ patch -p1 < ${CMAKE_SOURCE_DIR}/tools/depends/target/ffmpeg/pfcd_hevc_optimisations.patch ++ ) ++ + + find_program(BASH_COMMAND bash) + if(NOT BASH_COMMAND) +diff --git a/tools/depends/target/ffmpeg/CMakeLists.txt b/tools/depends/target/ffmpeg/CMakeLists.txt +index 4a2622216c..3afb989dcf 100644 +--- a/tools/depends/target/ffmpeg/CMakeLists.txt ++++ b/tools/depends/target/ffmpeg/CMakeLists.txt +@@ -18,6 +18,11 @@ if(CROSSCOMPILING) + message(STATUS "CROSS: ${ffmpeg_conf}") + endif() + ++#if(CORE_PLATFORM_NAME STREQUAL rbpi) ++ string(CONCAT CMAKE_C_FLAGS ${CMAKE_C_FLAGS} " -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux") ++ list(APPEND ffmpeg_conf --enable-rpi --disable-ffmpeg --disable-ffprobe) ++#endif() ++ + if(CMAKE_C_FLAGS) + list(APPEND ffmpeg_conf --extra-cflags=${CMAKE_C_FLAGS}) + endif() +-- +2.20.1 + + +From a9a7f16a39db1fcab3c47df6024fb6c98c314063 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 29 Apr 2019 20:52:03 +0100 +Subject: [PATCH 05/14] HACK: add videoplayer.usemmal setting to gbm.xml + +This reverts commit 2c94f63f62a124ed4024f01c3dafcf8f6dfebda0. +--- + system/settings/gbm.xml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/system/settings/gbm.xml b/system/settings/gbm.xml +index c5e4d98e0b..2335b5843e 100644 +--- a/system/settings/gbm.xml ++++ b/system/settings/gbm.xml +@@ -9,6 +9,11 @@ + + + ++ ++ 2 ++ true ++ ++ + + false + 2 +-- +2.20.1 + + +From cc4e38058d7d1afacfb8febd59ea68ae01c18d3f Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 25 Apr 2019 17:14:32 +0100 +Subject: [PATCH 06/14] gbm: Expose videoplayer.usedisplayasclock + +--- + system/settings/gbm.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/system/settings/gbm.xml b/system/settings/gbm.xml +index 2335b5843e..dffea009fe 100644 +--- a/system/settings/gbm.xml ++++ b/system/settings/gbm.xml +@@ -4,7 +4,7 @@ + + + +- false ++ true + false + + +-- +2.20.1 + + +From 18e97485734156146bc796bde8f0b82c0550d554 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 24 Mar 2019 11:07:25 +0100 +Subject: [PATCH 07/14] HACK: try to use MMAL with gbm + +Signed-off-by: Matthias Reichl +--- + cmake/platform/linux/gbm.cmake | 2 +- + xbmc/SystemGlobals.cpp | 4 -- + .../VideoRenderers/HwDecRender/MMALRenderer.h | 1 + + xbmc/platform/linux/CMakeLists.txt | 3 + + xbmc/platform/linux/RBP.cpp | 18 ++++++ + xbmc/platform/linux/RBP.h | 10 +++ + xbmc/windowing/gbm/CMakeLists.txt | 2 + + xbmc/windowing/gbm/VideoSyncPi.cpp | 62 +++++++++++++++++++ + xbmc/windowing/gbm/VideoSyncPi.h | 27 ++++++++ + .../windowing/gbm/WinSystemGbmGLESContext.cpp | 42 +++++++------ + xbmc/windowing/gbm/WinSystemGbmGLESContext.h | 3 +- + 11 files changed, 148 insertions(+), 26 deletions(-) + create mode 100644 xbmc/windowing/gbm/VideoSyncPi.cpp + create mode 100644 xbmc/windowing/gbm/VideoSyncPi.h + +diff --git a/cmake/platform/linux/gbm.cmake b/cmake/platform/linux/gbm.cmake +index e5b44ada46..b25ea7b0eb 100644 +--- a/cmake/platform/linux/gbm.cmake ++++ b/cmake/platform/linux/gbm.cmake +@@ -1,4 +1,4 @@ +-set(PLATFORM_REQUIRED_DEPS EGL GBM LibDRM LibInput Xkbcommon) ++set(PLATFORM_REQUIRED_DEPS EGL GBM LibDRM LibInput Xkbcommon MMAL) + set(PLATFORM_OPTIONAL_DEPS VAAPI) + + set(GBM_RENDER_SYSTEM "" CACHE STRING "Render system to use with GBM: \"gl\" or \"gles\"") +diff --git a/xbmc/SystemGlobals.cpp b/xbmc/SystemGlobals.cpp +index 435b1f5090..df1ae2cced 100644 +--- a/xbmc/SystemGlobals.cpp ++++ b/xbmc/SystemGlobals.cpp +@@ -24,9 +24,7 @@ std::map CSpecialProtocol::m_pathMap; + + #include "filesystem/ZipManager.h" + +-#ifdef TARGET_RASPBERRY_PI + #include "platform/linux/RBP.h" +-#endif + + CLangCodeExpander g_LangCodeExpander; + CLocalizeStrings g_localizeStrings; +@@ -42,8 +40,6 @@ std::map CSpecialProtocol::m_pathMap; + CAlarmClock g_alarmClock; + CSectionLoader g_sectionLoader; + +-#ifdef TARGET_RASPBERRY_PI + CRBP g_RBP; +-#endif + + CZipManager g_ZipManager; +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h +index 9718fb056d..03042edfb1 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h +@@ -21,6 +21,7 @@ + #include "threads/Thread.h" + #include "threads/IRunnable.h" + #include "utils/Geometry.h" ++#include "platform/linux/RBP.h" + + // worst case number of buffers. 12 for decoder. 8 for multi-threading in ffmpeg. NUM_BUFFERS for renderer. + // Note, generally these won't necessarily result in allocated pictures +diff --git a/xbmc/platform/linux/CMakeLists.txt b/xbmc/platform/linux/CMakeLists.txt +index f3d9b535bc..88076c3d5a 100644 +--- a/xbmc/platform/linux/CMakeLists.txt ++++ b/xbmc/platform/linux/CMakeLists.txt +@@ -48,6 +48,9 @@ if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + DllOMX.h + OMXClock.h + OMXCore.h) ++else() ++ list(APPEND SOURCES RBP.cpp) ++ list(APPEND HEADERS RBP.h) + endif() + + if(HAVE_SSE4_1) +diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp +index 9558e80afa..e7b11a5f73 100644 +--- a/xbmc/platform/linux/RBP.cpp ++++ b/xbmc/platform/linux/RBP.cpp +@@ -14,7 +14,9 @@ + #include "settings/SettingsComponent.h" + #include "utils/log.h" + ++#ifdef TARGET_RASPBERRY_PI + #include "cores/omxplayer/OMXImage.h" ++#endif + #include + + #include +@@ -66,9 +68,13 @@ typedef int vc_image_t_size_check[(sizeof(VC_IMAGE_T) == 64) * 2 - 1]; + CRBP::CRBP() + { + m_initialized = false; ++#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = false; ++#endif + m_DllBcmHost = new DllBcmHost(); ++#ifdef TARGET_RASPBERRY_PI + m_OMX = new COMXCore(); ++#endif + m_display = DISPMANX_NO_HANDLE; + m_mb = mbox_open(); + vcsm_init(); +@@ -79,7 +85,9 @@ CRBP::CRBP() + CRBP::~CRBP() + { + Deinitialize(); ++#ifdef TARGET_RASPBERRY_PI + delete m_OMX; ++#endif + delete m_DllBcmHost; + } + +@@ -95,9 +103,11 @@ bool CRBP::Initialize() + + m_DllBcmHost->bcm_host_init(); + ++#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = m_OMX->Initialize(); + if(!m_omx_initialized) + return false; ++#endif + + char response[80] = ""; + m_arm_mem = 0; +@@ -122,8 +132,10 @@ bool CRBP::Initialize() + if (!m_gui_resolution_limit) + m_gui_resolution_limit = m_gpu_mem < 128 ? 720:1080; + ++#ifdef TARGET_RASPBERRY_PI + g_OMXImage.Initialize(); + m_omx_image_init = true; ++#endif + return true; + } + +@@ -264,20 +276,26 @@ uint32_t CRBP::LastVsync() + + void CRBP::Deinitialize() + { ++#ifdef TARGET_RASPBERRY_PI + if (m_omx_image_init) + g_OMXImage.Deinitialize(); + + if(m_omx_initialized) + m_OMX->Deinitialize(); ++#endif + + m_DllBcmHost->bcm_host_deinit(); + + if(m_initialized) + m_DllBcmHost->Unload(); + ++#ifdef TARGET_RASPBERRY_PI + m_omx_image_init = false; ++#endif + m_initialized = false; ++#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = false; ++#endif + if (m_mb) + mbox_close(m_mb); + m_mb = 0; +diff --git a/xbmc/platform/linux/RBP.h b/xbmc/platform/linux/RBP.h +index aaddd14591..c4741fd60f 100644 +--- a/xbmc/platform/linux/RBP.h ++++ b/xbmc/platform/linux/RBP.h +@@ -19,7 +19,9 @@ + #endif + + #include "DllBCM.h" ++#ifdef TARGET_RASPBERRY_PI + #include "OMXCore.h" ++#endif + #include "xbmc/utils/CPUInfo.h" + #include "threads/CriticalSection.h" + #include "threads/Event.h" +@@ -91,7 +93,9 @@ public: + int GetGUIResolutionLimit() { return m_gui_resolution_limit; } + // stride can be null for packed output + unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); ++#ifdef TARGET_RASPBERRY_PI + DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } ++#endif + uint32_t LastVsync(int64_t &time); + uint32_t LastVsync(); + uint32_t WaitVsync(uint32_t target = ~0U); +@@ -102,20 +106,26 @@ public: + private: + DllBcmHost *m_DllBcmHost; + bool m_initialized; ++#ifdef TARGET_RASPBERRY_PI + bool m_omx_initialized; + bool m_omx_image_init; ++#endif + int m_arm_mem; + int m_gpu_mem; + int m_gui_resolution_limit; + bool m_codec_mpg2_enabled; + bool m_codec_wvc1_enabled; ++#ifdef TARGET_RASPBERRY_PI + COMXCore *m_OMX; ++#endif + DISPMANX_DISPLAY_HANDLE_T m_display; + CCriticalSection m_vsync_lock; + XbmcThreads::ConditionVariable m_vsync_cond; + uint32_t m_vsync_count; + int64_t m_vsync_time; ++#ifdef TARGET_RASPBERRY_PI + class DllLibOMXCore; ++#endif + CCriticalSection m_critSection; + + int m_mb; +diff --git a/xbmc/windowing/gbm/CMakeLists.txt b/xbmc/windowing/gbm/CMakeLists.txt +index 78c788c158..c3377e9a52 100644 +--- a/xbmc/windowing/gbm/CMakeLists.txt ++++ b/xbmc/windowing/gbm/CMakeLists.txt +@@ -1,5 +1,6 @@ + set(SOURCES OptionalsReg.cpp + WinSystemGbm.cpp ++ VideoSyncPi.cpp + GBMUtils.cpp + DRMUtils.cpp + DRMLegacy.cpp +@@ -9,6 +10,7 @@ set(SOURCES OptionalsReg.cpp + + set(HEADERS OptionalsReg.h + WinSystemGbm.h ++ VideoSyncPi.h + GBMUtils.h + DRMUtils.h + DRMLegacy.h +diff --git a/xbmc/windowing/gbm/VideoSyncPi.cpp b/xbmc/windowing/gbm/VideoSyncPi.cpp +new file mode 100644 +index 0000000000..fd12528011 +--- /dev/null ++++ b/xbmc/windowing/gbm/VideoSyncPi.cpp +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2005-2018 Team Kodi ++ * This file is part of Kodi - https://kodi.tv ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ * See LICENSES/README.md for more information. ++ */ ++ ++#include "VideoSyncPi.h" ++#include "ServiceBroker.h" ++#include "windowing/GraphicContext.h" ++#include "windowing/WinSystem.h" ++#include "utils/TimeUtils.h" ++#include "utils/log.h" ++#include "platform/linux/RBP.h" ++#include "threads/Thread.h" ++ ++bool CVideoSyncPi::Setup(PUPDATECLOCK func) ++{ ++ UpdateClock = func; ++ m_abort = false; ++ CServiceBroker::GetWinSystem()->Register(this); ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up RPi"); ++ return true; ++} ++ ++void CVideoSyncPi::Run(CEvent& stopEvent) ++{ ++ /* This shouldn't be very busy and timing is important so increase priority */ ++ CThread::GetCurrentThread()->SetPriority(CThread::GetCurrentThread()->GetPriority()+1); ++ ++ while (!stopEvent.Signaled() && !m_abort) ++ { ++ g_RBP.WaitVsync(); ++ uint64_t now = CurrentHostCounter(); ++ UpdateClock(1, now, m_refClock); ++ } ++} ++ ++void CVideoSyncPi::Cleanup() ++{ ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up RPi"); ++ CServiceBroker::GetWinSystem()->Unregister(this); ++} ++ ++float CVideoSyncPi::GetFps() ++{ ++ m_fps = CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS(); ++ CLog::Log(LOGDEBUG, "CVideoReferenceClock: fps: %.2f", m_fps); ++ return m_fps; ++} ++ ++void CVideoSyncPi::OnResetDisplay() ++{ ++ m_abort = true; ++} ++ ++void CVideoSyncPi::RefreshChanged() ++{ ++ if (m_fps != CServiceBroker::GetWinSystem()->GetGfxContext().GetFPS()) ++ m_abort = true; ++} +diff --git a/xbmc/windowing/gbm/VideoSyncPi.h b/xbmc/windowing/gbm/VideoSyncPi.h +new file mode 100644 +index 0000000000..e0c759fa7f +--- /dev/null ++++ b/xbmc/windowing/gbm/VideoSyncPi.h +@@ -0,0 +1,27 @@ ++/* ++ * Copyright (C) 2005-2018 Team Kodi ++ * This file is part of Kodi - https://kodi.tv ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ * See LICENSES/README.md for more information. ++ */ ++ ++#pragma once ++ ++#include "windowing/VideoSync.h" ++#include "guilib/DispResource.h" ++ ++class CVideoSyncPi : public CVideoSync, IDispResource ++{ ++public: ++ CVideoSyncPi(void *clock) : CVideoSync(clock) {}; ++ virtual bool Setup(PUPDATECLOCK func); ++ virtual void Run(CEvent& stopEvent); ++ virtual void Cleanup(); ++ virtual float GetFps(); ++ virtual void OnResetDisplay(); ++ virtual void RefreshChanged(); ++ ++private: ++ volatile bool m_abort; ++}; +diff --git a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp +index f763577117..e73381f350 100644 +--- a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp ++++ b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp +@@ -6,15 +6,12 @@ + * See LICENSES/README.md for more information. + */ + +-#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h" +-#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIME.h" +-#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.h" +- + #include "cores/RetroPlayer/process/gbm/RPProcessInfoGbm.h" + #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererGBM.h" + #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h" + #include "cores/VideoPlayer/DVDCodecs/DVDFactoryCodec.h" +-#include "cores/VideoPlayer/Process/gbm/ProcessInfoGBM.h" ++#include "cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.h" ++#include "cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h" + #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h" + #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h" + +@@ -22,6 +19,7 @@ + #include "platform/linux/XTimeUtils.h" + #include "utils/log.h" + #include "WinSystemGbmGLESContext.h" ++#include "VideoSyncPi.h" + + #include + #include +@@ -43,9 +41,10 @@ bool CWinSystemGbmGLESContext::InitWindowSystem() + { + VIDEOPLAYER::CRendererFactory::ClearRenderer(); + CDVDFactoryCodec::ClearHWAccels(); ++ CDVDFactoryCodec::ClearHWVideoCodecs(); ++ + CLinuxRendererGLES::Register(); + RETRO::CRPProcessInfoGbm::Register(); +- RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryGBM); + RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES); + + if (!CWinSystemGbmEGLContext::InitWindowSystemEGL(EGL_OPENGL_ES2_BIT, EGL_OPENGL_ES_API)) +@@ -53,20 +52,9 @@ bool CWinSystemGbmGLESContext::InitWindowSystem() + return false; + } + +- bool general, deepColor; +- m_vaapiProxy.reset(GBM::VaapiProxyCreate(m_DRM->GetRenderNodeFileDescriptor())); +- GBM::VaapiProxyConfig(m_vaapiProxy.get(), m_eglContext.GetEGLDisplay()); +- GBM::VAAPIRegisterRender(m_vaapiProxy.get(), general, deepColor); +- +- if (general) +- { +- GBM::VAAPIRegister(m_vaapiProxy.get(), deepColor); +- } +- +- CRendererDRMPRIMEGLES::Register(); +- CRendererDRMPRIME::Register(); +- CDVDVideoCodecDRMPRIME::Register(); +- VIDEOPLAYER::CProcessInfoGBM::Register(); ++ MMAL::CDecoder::Register(); ++ MMAL::CMMALRenderer::Register(); ++ MMAL::CMMALVideo::Register(); + + return true; + } +@@ -144,3 +132,17 @@ bool CWinSystemGbmGLESContext::CreateContext() + } + return true; + } ++ ++std::unique_ptr CWinSystemGbmGLESContext::GetVideoSync(void *clock) ++{ ++ std::unique_ptr pVSync(new CVideoSyncPi(clock)); ++ return pVSync; ++} ++ ++void CWinSystemGbmGLESContext::SetVSyncImpl(bool enable) ++{ ++ if (!m_eglContext.SetVSync(enable)) ++ { ++ CLog::Log(LOGERROR, "%s,Could not set egl vsync", __FUNCTION__); ++ } ++} +diff --git a/xbmc/windowing/gbm/WinSystemGbmGLESContext.h b/xbmc/windowing/gbm/WinSystemGbmGLESContext.h +index d80d9770d5..95954a606c 100644 +--- a/xbmc/windowing/gbm/WinSystemGbmGLESContext.h ++++ b/xbmc/windowing/gbm/WinSystemGbmGLESContext.h +@@ -34,7 +34,8 @@ public: + bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays) override; + void PresentRender(bool rendered, bool videoLayer) override; + protected: +- void SetVSyncImpl(bool enable) override { return; }; ++ void SetVSyncImpl(bool enable) override; ++ virtual std::unique_ptr GetVideoSync(void *clock) override; + void PresentRenderImpl(bool rendered) override {}; + bool CreateContext() override; + }; +-- +2.20.1 + + +From 21a4e178608b931f35128eb378d99657b5ecdf43 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 3 Apr 2019 19:19:45 +0100 +Subject: [PATCH 08/14] MMALRenderer: Avoid advanced deinterlace in gbm mode + +--- + .../VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +index fae5df73e2..e4a9a2c9ea 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +@@ -745,7 +745,9 @@ void CMMALRenderer::Run() + bool interlace = (omvb->mmal_buffer->flags & MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED) ? true:false; + + // advanced deinterlace requires 3 frames of context so disable when showing stills ++#if !defined(HAVE_GBM) + if (omvb->m_stills) ++#endif + { + if (interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED) + interlace_method = VS_INTERLACEMETHOD_MMAL_BOB; +-- +2.20.1 + + +From 9a03bf88878532faa76532105bb6298f28a78cd1 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 24 Apr 2019 16:22:27 +0100 +Subject: [PATCH 09/14] MMALRender: Move video plane behind GUI + +--- + .../VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +index e4a9a2c9ea..2114712c29 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +@@ -1280,6 +1280,9 @@ void CMMALRenderer::SetVideoRect(const CRect& InSrcRect, const CRect& InDestRect + region.noaspect = MMAL_TRUE; + region.mode = MMAL_DISPLAY_MODE_LETTERBOX; + ++ region.set |= MMAL_DISPLAY_SET_LAYER; ++ region.layer = -128; ++ + if (m_renderOrientation == 90) + region.transform = MMAL_DISPLAY_ROT90; + else if (m_renderOrientation == 180) +-- +2.20.1 + + +From 736818a17b48faf18e3bcdaa9f3069cded8ea6f9 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Fri, 26 Apr 2019 17:33:36 +0200 +Subject: [PATCH 10/14] WinSystemGbmGLESContext: register CProcessInfoPi + +Signed-off-by: Matthias Reichl +--- + xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt | 4 ++-- + xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp | 2 ++ + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt b/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt +index 1a41576405..2b0c66ebc7 100644 +--- a/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt ++++ b/xbmc/cores/VideoPlayer/Process/rbpi/CMakeLists.txt +@@ -1,7 +1,7 @@ +-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) ++# if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + set(SOURCES ProcessInfoPi.cpp) + + set(HEADERS ProcessInfoPi.h) + + core_add_library(processPi) +-endif() ++# endif() +diff --git a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp +index e73381f350..c4997cc2f4 100644 +--- a/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp ++++ b/xbmc/windowing/gbm/WinSystemGbmGLESContext.cpp +@@ -14,6 +14,7 @@ + #include "cores/VideoPlayer/DVDCodecs/Video/MMALCodec.h" + #include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h" + #include "cores/VideoPlayer/VideoRenderers/RenderFactory.h" ++#include "cores/VideoPlayer/Process/rbpi/ProcessInfoPi.h" + + #include "OptionalsReg.h" + #include "platform/linux/XTimeUtils.h" +@@ -44,6 +45,7 @@ bool CWinSystemGbmGLESContext::InitWindowSystem() + CDVDFactoryCodec::ClearHWVideoCodecs(); + + CLinuxRendererGLES::Register(); ++ CProcessInfoPi::Register(); + RETRO::CRPProcessInfoGbm::Register(); + RETRO::CRPProcessInfoGbm::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES); + +-- +2.20.1 + + +From 2958fa06af85e097f811a984cbaf718884e6a17e Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sun, 28 Apr 2019 10:57:11 +0200 +Subject: [PATCH 11/14] Screenshot: use RPi/dispmanx code to capture screenshot + +Signed-off-by: Matthias Reichl +--- + xbmc/utils/Screenshot.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/utils/Screenshot.cpp b/xbmc/utils/Screenshot.cpp +index 0616e24a18..ad82156384 100644 +--- a/xbmc/utils/Screenshot.cpp ++++ b/xbmc/utils/Screenshot.cpp +@@ -17,7 +17,7 @@ + + #include "pictures/Picture.h" + +-#ifdef TARGET_RASPBERRY_PI ++#if 1 //#ifdef TARGET_RASPBERRY_PI + #include "platform/linux/RBP.h" + #endif + +@@ -62,7 +62,7 @@ CScreenshotSurface::~CScreenshotSurface() + + bool CScreenshotSurface::capture() + { +-#if defined(TARGET_RASPBERRY_PI) ++#if 1 //#if defined(TARGET_RASPBERRY_PI) + g_RBP.GetDisplaySize(m_width, m_height); + m_buffer = g_RBP.CaptureDisplay(m_width, m_height, &m_stride, true, false); + if (!m_buffer) +-- +2.20.1 + + +From 0412bf4ffbd7bc1695a2e9e975ce7ca6ef7fd51c Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 25 Apr 2019 17:11:53 +0100 +Subject: [PATCH 12/14] RBP: Hack: open display after changing hdmi mode + +--- + xbmc/platform/linux/RBP.cpp | 6 ++++-- + xbmc/platform/xbmc.cpp | 4 ++-- + xbmc/windowing/gbm/DRMAtomic.cpp | 12 +++++++++++- + xbmc/windowing/gbm/DRMAtomic.h | 2 ++ + 4 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp +index e7b11a5f73..255f4640c0 100644 +--- a/xbmc/platform/linux/RBP.cpp ++++ b/xbmc/platform/linux/RBP.cpp +@@ -162,6 +162,7 @@ static void vsync_callback_static(DISPMANX_UPDATE_HANDLE_T u, void *arg) + + DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) + { ++ DISPMANX_DISPLAY_HANDLE_T last_display = m_display; + CSingleLock lock(m_critSection); + if (m_display == DISPMANX_NO_HANDLE) + { +@@ -169,12 +170,14 @@ DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device) + int s = vc_dispmanx_vsync_callback(m_display, vsync_callback_static, (void *)this); + assert(s == 0); + } ++ CLog::Log(LOGDEBUG, "CRBP::%s device:%d m_display:%x (%x)", __FUNCTION__, device, m_display, last_display); + return m_display; + } + + void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display) + { + CSingleLock lock(m_critSection); ++ CLog::Log(LOGDEBUG, "CRBP::%s display:%x m_display:%x", __FUNCTION__, display, m_display); + assert(display == m_display); + int s = vc_dispmanx_vsync_callback(m_display, NULL, NULL); + assert(s == 0); +@@ -244,7 +247,6 @@ void CRBP::VSyncCallback() + uint32_t CRBP::WaitVsync(uint32_t target) + { + CSingleLock vlock(m_vsync_lock); +- DISPMANX_DISPLAY_HANDLE_T display = m_display; + XbmcThreads::EndTime delay(50); + if (target == ~0U) + target = m_vsync_count+1; +@@ -256,7 +258,7 @@ uint32_t CRBP::WaitVsync(uint32_t target) + break; + } + if ((signed)(m_vsync_count - target) < 0) +- CLog::Log(LOGDEBUG, "CRBP::%s no vsync %d/%d display:%x(%x) delay:%d", __FUNCTION__, m_vsync_count, target, m_display, display, delay.MillisLeft()); ++ CLog::Log(LOGDEBUG, "CRBP::%s no vsync %d/%d display:%x delay:%d", __FUNCTION__, m_vsync_count, target, m_display, delay.MillisLeft()); + + return m_vsync_count; + } +diff --git a/xbmc/platform/xbmc.cpp b/xbmc/platform/xbmc.cpp +index e9f39178ca..4617c196d8 100644 +--- a/xbmc/platform/xbmc.cpp ++++ b/xbmc/platform/xbmc.cpp +@@ -8,7 +8,7 @@ + + #include "Application.h" + +-#ifdef TARGET_RASPBERRY_PI ++#if 1//def TARGET_RASPBERRY_PI + #include "platform/linux/RBP.h" + #endif + +@@ -36,7 +36,7 @@ extern "C" int XBMC_Run(bool renderGUI, const CAppParamParser ¶ms) + return status; + } + +-#ifdef TARGET_RASPBERRY_PI ++#if 1//def TARGET_RASPBERRY_PI + if(!g_RBP.Initialize()) + return false; + g_RBP.LogFirmwareVersion(); +diff --git a/xbmc/windowing/gbm/DRMAtomic.cpp b/xbmc/windowing/gbm/DRMAtomic.cpp +index 0299fc9caa..de2c905e61 100644 +--- a/xbmc/windowing/gbm/DRMAtomic.cpp ++++ b/xbmc/windowing/gbm/DRMAtomic.cpp +@@ -118,10 +118,20 @@ void CDRMAtomic::FlipPage(struct gbm_bo *bo, bool rendered, bool videoLayer) + if (m_need_modeset) + { + flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; +- m_need_modeset = false; ++ if (m_dispman_display != DISPMANX_NO_HANDLE) ++ { ++ g_RBP.CloseDisplay(m_dispman_display); ++ m_dispman_display = DISPMANX_NO_HANDLE; ++ } + } + + DrmAtomicCommit(!drm_fb ? 0 : drm_fb->fb_id, flags, rendered, videoLayer); ++ ++ if (m_need_modeset) ++ { ++ m_need_modeset = false; ++ m_dispman_display = g_RBP.OpenDisplay(0); ++ } + } + + bool CDRMAtomic::InitDrm() +diff --git a/xbmc/windowing/gbm/DRMAtomic.h b/xbmc/windowing/gbm/DRMAtomic.h +index 1aa96127f4..3dcb449103 100644 +--- a/xbmc/windowing/gbm/DRMAtomic.h ++++ b/xbmc/windowing/gbm/DRMAtomic.h +@@ -9,6 +9,7 @@ + #pragma once + + #include "DRMUtils.h" ++#include "platform/linux/RBP.h" + + namespace KODI + { +@@ -36,6 +37,7 @@ private: + bool m_need_modeset; + bool m_active = true; + drmModeAtomicReq *m_req = nullptr; ++ DISPMANX_ELEMENT_HANDLE_T m_dispman_display = 0; + }; + + } +-- +2.20.1 + + +From bd3966f39af236f5d332781e1446a7eb3aa56c49 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 17 May 2019 18:54:03 +0100 +Subject: [PATCH 13/14] RPI: Some fixes for 10-bit geometry + +--- + .../DVDCodecs/Video/MMALFFmpeg.cpp | 12 +++++--- + .../HwDecRender/MMALRenderer.cpp | 5 +++- + .../VideoRenderers/HwDecRender/MMALRenderer.h | 4 +-- + xbmc/platform/linux/RBP.cpp | 29 +++++++++++++++++++ + xbmc/platform/linux/RBP.h | 4 +++ + 5 files changed, 47 insertions(+), 7 deletions(-) + +diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +index 854f34fa62..030ca1b7bf 100644 +--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp ++++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +@@ -58,11 +58,13 @@ void CMMALYUVBuffer::GetPlanes(uint8_t*(&planes)[YuvImage::MAX_PLANES]) + AVRpiZcFrameGeometry geo = pool->GetGeometry(); + + if (VERBOSE) +- CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %dx%d %dx%d (%dx%d %dx%d)", CLASSNAME, __FUNCTION__, geo.getStrideY(), geo.getHeightY(), geo.getStrideC(), geo.getHeightC(), Width(), Height(), AlignedWidth(), AlignedHeight()); ++ CLog::Log(LOGDEBUG, LOGVIDEO, "%s::%s %dx%d %dx%d (%dx%d %dx%d) ofu:%d szy:%d szu:%d yc:%d", CLASSNAME, __FUNCTION__, ++ geo.getHeightY(), geo.getHeightC(), geo.getStrideY(), geo.getStrideC(), Width(), Height(), AlignedWidth(), AlignedHeight(), ++ geo.getOffsetU(), geo.getSizeY(), geo.getSizeC(), geo.getStripeIsYc() ); + + planes[0] = GetMemPtr(); + if (planes[0] && geo.getPlanesC() >= 1) +- planes[1] = planes[0] + geo.getSizeY(); ++ planes[1] = planes[0] + geo.getOffsetU(); + if (planes[1] && geo.getPlanesC() >= 2) + planes[2] = planes[1] + geo.getSizeC(); + } +@@ -78,7 +80,7 @@ void CMMALYUVBuffer::GetStrides(int(&strides)[YuvImage::MAX_PLANES]) + strides[1] = geo.getStrideC(); + strides[2] = geo.getStrideC(); + if (geo.getStripes() > 1) +- strides[3] = geo.getHeightY() + geo.getHeightC(); // abuse: strides[3] = stripe stride ++ strides[3] = geo.getStripeIsYc() ? geo.getHeightY() + geo.getHeightC() : geo.getHeightY(); // abuse: strides[3] = stripe stride + } + + void CMMALYUVBuffer::SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) +@@ -190,7 +192,8 @@ int CDecoder::FFGetBuffer(AVCodecContext *avctx, AVFrame *frame, int flags) + { + int aligned_width = frame->width; + int aligned_height = frame->height; +- if (pool->Encoding() != MMAL_ENCODING_YUVUV128 && pool->Encoding() != MMAL_ENCODING_YUVUV64_16) ++ if (dec->m_fmt != AV_PIX_FMT_SAND128 && dec->m_fmt != AV_PIX_FMT_SAND64_10 && dec->m_fmt != AV_PIX_FMT_SAND64_16 && ++ dec->m_fmt != AV_PIX_FMT_RPI && dec->m_fmt != AV_PIX_FMT_RPI4_8 && dec->m_fmt != AV_PIX_FMT_RPI4_10) + { + // ffmpeg requirements + AlignedSize(dec->m_avctx, aligned_width, aligned_height); +@@ -287,6 +290,7 @@ CDVDVideoCodec::VCReturn CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) + { + if ((frame->format != AV_PIX_FMT_YUV420P && frame->format != AV_PIX_FMT_YUV420P10 && frame->format != AV_PIX_FMT_YUV420P12 && frame->format != AV_PIX_FMT_YUV420P14 && frame->format != AV_PIX_FMT_YUV420P16 && + frame->format != AV_PIX_FMT_SAND128 && frame->format != AV_PIX_FMT_SAND64_10 && frame->format != AV_PIX_FMT_SAND64_16 && ++ frame->format != AV_PIX_FMT_RPI && frame->format != AV_PIX_FMT_RPI4_8 && frame->format != AV_PIX_FMT_RPI4_10 && + frame->format != AV_PIX_FMT_BGR0 && frame->format != AV_PIX_FMT_RGB565LE) || + frame->buf[1] != nullptr || frame->buf[0] == nullptr) + { +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +index 2114712c29..d2f3d21781 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.cpp +@@ -194,6 +194,9 @@ std::vector CMMALPool::mmal_encoding_table = + { AV_PIX_FMT_YUV420P14,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_YUV420P16,MMAL_ENCODING_I420_16, }, + { AV_PIX_FMT_SAND128, MMAL_ENCODING_YUVUV128 }, ++ { AV_PIX_FMT_RPI, MMAL_ENCODING_YUVUV128 }, ++ { AV_PIX_FMT_RPI4_8, MMAL_ENCODING_YUVUV128 }, ++ { AV_PIX_FMT_RPI4_10, MMAL_ENCODING_YUV10_COL }, + { AV_PIX_FMT_SAND64_10,MMAL_ENCODING_YUVUV64_16 }, + { AV_PIX_FMT_SAND64_16,MMAL_ENCODING_YUVUV64_16 }, + { AV_PIX_FMT_RGBA, MMAL_ENCODING_RGBA, }, +@@ -234,7 +237,7 @@ void CMMALPool::Configure(AVPixelFormat format, int width, int height, int align + if (m_mmal_format != MMAL_ENCODING_UNKNOWN) + { + m_geo = g_RBP.GetFrameGeometry(m_mmal_format, alignedWidth, alignedHeight); +- if (m_mmal_format != MMAL_ENCODING_YUVUV128 && m_mmal_format != MMAL_ENCODING_YUVUV64_16 ) ++ if (m_mmal_format != MMAL_ENCODING_YUVUV128 && m_mmal_format != MMAL_ENCODING_YUVUV64_16 && m_mmal_format != MMAL_ENCODING_YUV10_COL ) + { + if (alignedWidth) + { +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h +index 03042edfb1..644174dfeb 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/MMALRenderer.h +@@ -59,8 +59,8 @@ public: + static uint32_t TranslateFormat(AVPixelFormat pixfmt); + virtual int Width() { return m_width; } + virtual int Height() { return m_height; } +- virtual int AlignedWidth() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 || m_geo.getBytesPerPixel() == 0 ? 0 : m_geo.getStrideY() / m_geo.getBytesPerPixel(); } +- virtual int AlignedHeight() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 ? 0 : m_geo.getHeightY(); } ++ virtual int AlignedWidth() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 || m_mmal_format == MMAL_ENCODING_YUV10_COL || m_geo.getBytesPerPixel() == 0 ? 0 : m_geo.getStrideY() / m_geo.getBytesPerPixel(); } ++ virtual int AlignedHeight() { return m_mmal_format == MMAL_ENCODING_YUVUV128 || m_mmal_format == MMAL_ENCODING_YUVUV64_16 || m_mmal_format == MMAL_ENCODING_YUV10_COL ? 0 : m_geo.getHeightY(); } + virtual int BitsPerPixel() { return m_geo.getBitsPerPixel(); } + virtual uint32_t &Encoding() { return m_mmal_format; } + virtual int Size() { return m_size; } +diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp +index 255f4640c0..6c045e9674 100644 +--- a/xbmc/platform/linux/RBP.cpp ++++ b/xbmc/platform/linux/RBP.cpp +@@ -459,6 +459,7 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi + geo.setHeightY((video_height + 15) & ~15); + geo.setHeightC(geo.getHeightY() >> 1); + geo.setPlanesC(2); ++ geo.setStripeIsYc(1); + break; + case MMAL_ENCODING_I420_16: + geo.setBitsPerPixel(10); +@@ -467,6 +468,7 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi + geo.setHeightY((video_height + 15) & ~15); + geo.setHeightC(geo.getHeightY() >> 1); + geo.setPlanesC(2); ++ geo.setStripeIsYc(1); + break; + case MMAL_ENCODING_OPAQUE: + geo.setStrideY(video_width); +@@ -487,6 +489,14 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi + geo.setHeightC(img.pitch / stripe_w - geo.getHeightY()); + geo.setPlanesC(1); + geo.setStripes((video_width + stripe_w - 1) / stripe_w); ++ geo.setStripeIsYc(1); ++ if (geo.getHeightY() * stripe_w > img.pitch) ++ { ++ // "tall" sand - all C blocks now follow Y ++ geo.setHeightY(img.pitch / stripe_w); ++ geo.setHeightC(geo.getHeightY()); ++ geo.setStripeIsYc(0); ++ } + break; + } + case MMAL_ENCODING_YUVUV64_16: +@@ -505,6 +515,25 @@ AVRpiZcFrameGeometry CRBP::GetFrameGeometry(uint32_t encoding, unsigned short vi + geo.setHeightC(img.pitch / stripe_w - geo.getHeightY()); + geo.setPlanesC(1); + geo.setStripes((video_width * 2 + stripe_w - 1) / stripe_w); ++ geo.setStripeIsYc(1); ++ break; ++ } ++ case MMAL_ENCODING_YUV10_COL: ++ { ++ VC_IMAGE_T img = {}; ++ img.type = VC_IMAGE_YUV10COL; ++ img.width = video_width; ++ img.height = video_height; ++ int rc = get_image_params(GetMBox(), &img); ++ assert(rc == 0); ++ const unsigned int stripe_w = 128; ++ geo.setStrideY(stripe_w); ++ geo.setStrideC(stripe_w); ++ geo.setHeightY(((intptr_t)img.extra.uv.u - (intptr_t)img.image_data) / stripe_w); ++ geo.setHeightC(img.pitch / stripe_w - geo.getHeightY()); ++ geo.setPlanesC(1); ++ geo.setStripes(((video_width * 4 + 2) / 3 + stripe_w - 1) / stripe_w); ++ geo.setStripeIsYc(1); + break; + } + default: assert(0); +diff --git a/xbmc/platform/linux/RBP.h b/xbmc/platform/linux/RBP.h +index c4741fd60f..63e02a1826 100644 +--- a/xbmc/platform/linux/RBP.h ++++ b/xbmc/platform/linux/RBP.h +@@ -38,9 +38,11 @@ public: + unsigned int getStripes() { return stripes; } + unsigned int getBitsPerPixel() { return bits_per_pixel; } + unsigned int getBytesPerPixel() { return (bits_per_pixel + 7) >> 3; } ++ unsigned int getStripeIsYc() { return stripe_is_yc; } + unsigned int getSizeY() { return stride_y * height_y; } + unsigned int getSizeC() { return stride_c * height_c; } + unsigned int getSize() { return (getSizeY() + getSizeC() * getPlanesC()) * getStripes(); } ++ unsigned int getOffsetU() { return stripe_is_yc ? getSizeY() : getSizeY() * stripes; } + void setStrideY(unsigned int v) { stride_y = v; } + void setHeightY(unsigned int v) { height_y = v; } + void setStrideC(unsigned int v) { stride_c = v; } +@@ -49,6 +51,7 @@ public: + void setStripes(unsigned int v) { stripes = v; } + void setBitsPerPixel(unsigned int v) { bits_per_pixel = v; } + void setBytesPerPixel(unsigned int v) { bits_per_pixel = v * 8; } ++ void setStripeIsYc(unsigned int v) { stripe_is_yc = v; } + private: + unsigned int stride_y = 0; + unsigned int height_y = 0; +@@ -57,6 +60,7 @@ private: + unsigned int planes_c = 0; + unsigned int stripes = 0; + unsigned int bits_per_pixel = 0; ++ unsigned int stripe_is_yc = 0; + }; + + class CGPUMEM +-- +2.20.1 + + +From 3a51e92daaeb528d001f071d00f01d9b513e5e56 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 17 May 2019 18:59:25 +0100 +Subject: [PATCH 14/14] RPI: Increase number of referenced frames + +--- + xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +index 030ca1b7bf..1dfcf1cef2 100644 +--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp ++++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/MMALFFmpeg.cpp +@@ -364,7 +364,7 @@ CDVDVideoCodec::VCReturn CDecoder::Check(AVCodecContext* avctx) + + unsigned CDecoder::GetAllowedReferences() + { +- return 6; ++ return 7; + } + + IHardwareDecoder* CDecoder::Create(CDVDStreamInfo &hint, CProcessInfo &processInfo, AVPixelFormat fmt) +-- +2.20.1 + diff --git a/projects/RPi/devices/RPi4/patches/kodi/kodi-002-add-pisink.patch b/projects/RPi/devices/RPi4/patches/kodi/kodi-002-add-pisink.patch new file mode 100644 index 0000000000..145542295b --- /dev/null +++ b/projects/RPi/devices/RPi4/patches/kodi/kodi-002-add-pisink.patch @@ -0,0 +1,206 @@ +From 8f0d283542fa8c55f2a9cdd520271b0b471e3393 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 10 Jun 2019 22:07:55 +0100 +Subject: [PATCH] RBP: add PiSink + +--- + xbmc/cores/AudioEngine/CMakeLists.txt | 3 +++ + xbmc/platform/linux/CMakeLists.txt | 10 +++++----- + xbmc/platform/linux/RBP.cpp | 24 ++++++++++++------------ + xbmc/platform/linux/RBP.h | 22 +++++++++++----------- + xbmc/windowing/gbm/WinSystemGbm.cpp | 2 ++ + 5 files changed, 33 insertions(+), 28 deletions(-) + +diff --git a/xbmc/cores/AudioEngine/CMakeLists.txt b/xbmc/cores/AudioEngine/CMakeLists.txt +index 060c6a960d..e5b80cf54a 100644 +--- a/xbmc/cores/AudioEngine/CMakeLists.txt ++++ b/xbmc/cores/AudioEngine/CMakeLists.txt +@@ -101,6 +101,9 @@ if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + Sinks/AESinkPi.h) + endif() + ++ list(APPEND SOURCES Sinks/AESinkPi.cpp) ++ list(APPEND HEADERS Sinks/AESinkPi.h) ++ + if(CORE_SYSTEM_NAME STREQUAL osx) + list(APPEND SOURCES Sinks/AESinkDARWINOSX.cpp + Sinks/osx/AEDeviceEnumerationOSX.cpp +diff --git a/xbmc/platform/linux/CMakeLists.txt b/xbmc/platform/linux/CMakeLists.txt +index 88076c3d5a..16cdd478be 100644 +--- a/xbmc/platform/linux/CMakeLists.txt ++++ b/xbmc/platform/linux/CMakeLists.txt +@@ -39,7 +39,7 @@ if(DBUS_FOUND) + DBusUtil.h) + endif() + +-if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) ++#if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + list(APPEND SOURCES RBP.cpp + OMXClock.cpp + OMXCore.cpp) +@@ -48,10 +48,10 @@ if(CORE_PLATFORM_NAME_LC STREQUAL rbpi) + DllOMX.h + OMXClock.h + OMXCore.h) +-else() +- list(APPEND SOURCES RBP.cpp) +- list(APPEND HEADERS RBP.h) +-endif() ++#else() ++# list(APPEND SOURCES RBP.cpp) ++# list(APPEND HEADERS RBP.h) ++#endif() + + if(HAVE_SSE4_1) + add_subdirectory(sse4) +diff --git a/xbmc/platform/linux/RBP.cpp b/xbmc/platform/linux/RBP.cpp +index 6c045e9674..9ff4ed4e6f 100644 +--- a/xbmc/platform/linux/RBP.cpp ++++ b/xbmc/platform/linux/RBP.cpp +@@ -68,13 +68,13 @@ typedef int vc_image_t_size_check[(sizeof(VC_IMAGE_T) == 64) * 2 - 1]; + CRBP::CRBP() + { + m_initialized = false; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = false; +-#endif ++//#endif + m_DllBcmHost = new DllBcmHost(); +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + m_OMX = new COMXCore(); +-#endif ++//#endif + m_display = DISPMANX_NO_HANDLE; + m_mb = mbox_open(); + vcsm_init(); +@@ -103,11 +103,11 @@ bool CRBP::Initialize() + + m_DllBcmHost->bcm_host_init(); + +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = m_OMX->Initialize(); + if(!m_omx_initialized) + return false; +-#endif ++//#endif + + char response[80] = ""; + m_arm_mem = 0; +@@ -278,13 +278,13 @@ uint32_t CRBP::LastVsync() + + void CRBP::Deinitialize() + { +-#ifdef TARGET_RASPBERRY_PI +- if (m_omx_image_init) +- g_OMXImage.Deinitialize(); ++//#ifdef TARGET_RASPBERRY_PI ++// if (m_omx_image_init) ++// g_OMXImage.Deinitialize(); + + if(m_omx_initialized) + m_OMX->Deinitialize(); +-#endif ++//#endif + + m_DllBcmHost->bcm_host_deinit(); + +@@ -295,9 +295,9 @@ void CRBP::Deinitialize() + m_omx_image_init = false; + #endif + m_initialized = false; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + m_omx_initialized = false; +-#endif ++//#endif + if (m_mb) + mbox_close(m_mb); + m_mb = 0; +diff --git a/xbmc/platform/linux/RBP.h b/xbmc/platform/linux/RBP.h +index 63e02a1826..d3f46d34a1 100644 +--- a/xbmc/platform/linux/RBP.h ++++ b/xbmc/platform/linux/RBP.h +@@ -19,9 +19,9 @@ + #endif + + #include "DllBCM.h" +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + #include "OMXCore.h" +-#endif ++//#endif + #include "xbmc/utils/CPUInfo.h" + #include "threads/CriticalSection.h" + #include "threads/Event.h" +@@ -97,9 +97,9 @@ public: + int GetGUIResolutionLimit() { return m_gui_resolution_limit; } + // stride can be null for packed output + unsigned char *CaptureDisplay(int width, int height, int *stride, bool swap_red_blue, bool video_only = true); +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } +-#endif ++//#endif + uint32_t LastVsync(int64_t &time); + uint32_t LastVsync(); + uint32_t WaitVsync(uint32_t target = ~0U); +@@ -110,26 +110,26 @@ public: + private: + DllBcmHost *m_DllBcmHost; + bool m_initialized; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + bool m_omx_initialized; +- bool m_omx_image_init; +-#endif ++ //bool m_omx_image_init; ++//#endif + int m_arm_mem; + int m_gpu_mem; + int m_gui_resolution_limit; + bool m_codec_mpg2_enabled; + bool m_codec_wvc1_enabled; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + COMXCore *m_OMX; +-#endif ++//#endif + DISPMANX_DISPLAY_HANDLE_T m_display; + CCriticalSection m_vsync_lock; + XbmcThreads::ConditionVariable m_vsync_cond; + uint32_t m_vsync_count; + int64_t m_vsync_time; +-#ifdef TARGET_RASPBERRY_PI ++//#ifdef TARGET_RASPBERRY_PI + class DllLibOMXCore; +-#endif ++//#endif + CCriticalSection m_critSection; + + int m_mb; +diff --git a/xbmc/windowing/gbm/WinSystemGbm.cpp b/xbmc/windowing/gbm/WinSystemGbm.cpp +index 9ad1f2daf1..418e0cf8b1 100644 +--- a/xbmc/windowing/gbm/WinSystemGbm.cpp ++++ b/xbmc/windowing/gbm/WinSystemGbm.cpp +@@ -25,6 +25,7 @@ + #include "DRMLegacy.h" + #include "OffScreenModeSetting.h" + #include "messaging/ApplicationMessenger.h" ++#include "cores/AudioEngine/Sinks/AESinkPi.h" + + using namespace KODI::WINDOWING::GBM; + +@@ -33,6 +34,7 @@ CWinSystemGbm::CWinSystemGbm() : + m_GBM(new CGBMUtils), + m_libinput(new CLibInputHandler) + { ++ CAESinkPi::Register(); + OPTIONALS::ALSARegister(); + OPTIONALS::PulseAudioRegister(); + +-- +2.20.1 + diff --git a/projects/RPi/devices/RPi4/patches/kodi/kodi-010-PR16063-Leia-limit-guisize.patch b/projects/RPi/devices/RPi4/patches/kodi/kodi-010-PR16063-Leia-limit-guisize.patch new file mode 100644 index 0000000000..6dbfee91d1 --- /dev/null +++ b/projects/RPi/devices/RPi4/patches/kodi/kodi-010-PR16063-Leia-limit-guisize.patch @@ -0,0 +1,150 @@ +From b2ad605c9ae4b3e8bf5447562aea095fa094e66a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 30 May 2019 21:36:32 +0000 +Subject: [PATCH] windowing/gbm: add option to limit gui size + +--- + .../resources/strings.po | 44 ++++++++++++++++++- + system/settings/gbm.xml | 15 +++++++ + xbmc/windowing/gbm/DRMUtils.cpp | 33 +++++++++++++- + 3 files changed, 90 insertions(+), 2 deletions(-) + +diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po +index 9c9161a99323..11cdf4aba26c 100644 +--- a/addons/resource.language.en_gb/resources/strings.po ++++ b/addons/resource.language.en_gb/resources/strings.po +@@ -7266,7 +7266,49 @@ msgctxt "#13465" + msgid "EGL" + msgstr "" + +-#empty strings from id 13466 to 13504 ++#. Option for setting Limit GUI Size ++#: system/settings/gbm.xml ++msgctxt "#13466" ++msgid "Limit GUI Size" ++msgstr "" ++ ++#. Description of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13467" ++msgid "This option limits GUI size for screen resolutions above 1080p. Requires restart." ++msgstr "" ++ ++#. String for options 1 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13468" ++msgid "No limit" ++msgstr "" ++ ++#. String for options 2 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13469" ++msgid "720p" ++msgstr "" ++ ++#. String for options 3 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13470" ++msgid "1080p / 720p (>30hz)" ++msgstr "" ++ ++#. String for options 4 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13471" ++msgid "1080p" ++msgstr "" ++ ++#. String for options 5 of setting with label #13466 "Limit GUI Size" ++#: system/settings/gbm.xml ++msgctxt "#13472" ++msgid "No limit / 1080p (>30hz)" ++msgstr "" ++ ++#empty strings from id 13473 to 13504 + + #: system/settings/settings.xml + msgctxt "#13505" +diff --git a/system/settings/gbm.xml b/system/settings/gbm.xml +index c5e4d98e0bef..6492b08ef5f2 100644 +--- a/system/settings/gbm.xml ++++ b/system/settings/gbm.xml +@@ -41,6 +41,21 @@ + + false + ++ ++ false ++ 3 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + 3 + false +diff --git a/xbmc/windowing/gbm/DRMUtils.cpp b/xbmc/windowing/gbm/DRMUtils.cpp +index 48f0bc40bcf9..c6031bf67c41 100644 +--- a/xbmc/windowing/gbm/DRMUtils.cpp ++++ b/xbmc/windowing/gbm/DRMUtils.cpp +@@ -17,14 +17,21 @@ + #include + + #include "platform/linux/XTimeUtils.h" +-#include "utils/log.h" ++#include "settings/Settings.h" ++#include "settings/SettingsComponent.h" + #include "utils/StringUtils.h" ++#include "utils/log.h" + #include "windowing/GraphicContext.h" + + #include "DRMUtils.h" + + using namespace KODI::WINDOWING::GBM; + ++namespace ++{ ++const std::string SETTING_VIDEOSCREEN_LIMITGUISIZE = "videoscreen.limitguisize"; ++} ++ + CDRMUtils::CDRMUtils() + : m_connector(new connector) + , m_encoder(new encoder) +@@ -762,6 +769,30 @@ RESOLUTION_INFO CDRMUtils::GetResolutionInfo(drmModeModeInfoPtr mode) + res.iWidth = res.iScreenWidth; + res.iHeight = res.iScreenHeight; + ++ int limit = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(SETTING_VIDEOSCREEN_LIMITGUISIZE); ++ if (limit > 0 && res.iScreenWidth > 1920 && res.iScreenHeight > 1080) ++ { ++ switch (limit) ++ { ++ case 1: // 720p ++ res.iWidth = 1280; ++ res.iHeight = 720; ++ break; ++ case 2: // 1080p / 720p (>30hz) ++ res.iWidth = mode->vrefresh > 30 ? 1280 : 1920; ++ res.iHeight = mode->vrefresh > 30 ? 720 : 1080; ++ break; ++ case 3: // 1080p ++ res.iWidth = 1920; ++ res.iHeight = 1080; ++ break; ++ case 4: // No limit / 1080p (>30hz) ++ res.iWidth = mode->vrefresh > 30 ? 1920 : res.iScreenWidth; ++ res.iHeight = mode->vrefresh > 30 ? 1080 : res.iScreenHeight; ++ break; ++ } ++ } ++ + if (mode->clock % 5 != 0) + res.fRefreshRate = static_cast(mode->vrefresh) * (1000.0f/1001.0f); + else diff --git a/projects/RPi/devices/Slice/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch b/projects/RPi/devices/Slice/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch new file mode 120000 index 0000000000..f1fa7c5050 --- /dev/null +++ b/projects/RPi/devices/Slice/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch @@ -0,0 +1 @@ +../../../RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch \ No newline at end of file diff --git a/projects/RPi/devices/Slice3/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch b/projects/RPi/devices/Slice3/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch new file mode 120000 index 0000000000..f1fa7c5050 --- /dev/null +++ b/projects/RPi/devices/Slice3/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch @@ -0,0 +1 @@ +../../../RPi2/patches/ffmpeg/ffmpeg-001-pfcd_hevc_optimisations.patch \ No newline at end of file diff --git a/projects/RPi/filesystem/usr/share/alsa/cards/bcm2835_alsa.conf b/projects/RPi/filesystem/usr/share/alsa/cards/bcm2835_alsa.conf new file mode 100644 index 0000000000..71b23fadb4 --- /dev/null +++ b/projects/RPi/filesystem/usr/share/alsa/cards/bcm2835_alsa.conf @@ -0,0 +1,37 @@ + +bcm2835_alsa.pcm.iec958.0 { + @args [ CARD AES0 AES1 AES2 AES3 ] + @args.CARD { + type string + } + @args.AES0 { + type integer + } + @args.AES1 { + type integer + } + @args.AES2 { + type integer + } + @args.AES3 { + type integer + } + type hooks + slave.pcm { + type hw + card $CARD + device 1 + } + hooks.0 { + type ctl_elems + hook_args [ + { + interface PCM + name "IEC958 Playback Default" + lock true + preserve true + value [ $AES0 $AES1 $AES2 $AES3 ] + } + ] + } +} diff --git a/projects/RPi/options b/projects/RPi/options index 3b0654d979..4e80d70494 100644 --- a/projects/RPi/options +++ b/projects/RPi/options @@ -12,6 +12,9 @@ TARGET_CPU="arm1176jzf-s" elif [ "$DEVICE" = "RPi2" -o "$DEVICE" = "Slice3" ]; then TARGET_CPU="cortex-a7" + elif [ "$DEVICE" = "RPi4" ]; then + TARGET_CPU="cortex-a53" + TARGET_CPU_FLAGS="+crc" fi # TARGET_FLOAT: @@ -27,6 +30,8 @@ TARGET_FPU="vfp" elif [ "$DEVICE" = "RPi2" -o "$DEVICE" = "Slice3" ]; then TARGET_FPU="neon-vfpv4" + elif [ "$DEVICE" = "RPi4" ]; then + TARGET_FPU="neon-fp-armv8" fi TARGET_FEATURES="32bit" ;; @@ -116,7 +121,7 @@ # for a list of additional drivers see packages/linux-drivers # Space separated list is supported, # e.g. ADDITIONAL_DRIVERS="DRIVER1 DRIVER2" - ADDITIONAL_DRIVERS="$ADDITIONAL_DRIVERS rpi-cirrus-config" + ADDITIONAL_DRIVERS="$ADDITIONAL_DRIVERS rpi-cirrus-config bcm2835-driver" # build and install driver addons (yes / no) DRIVER_ADDONS_SUPPORT="yes" diff --git a/scripts/image b/scripts/image index 452decdcb1..5cfb2f8f86 100755 --- a/scripts/image +++ b/scripts/image @@ -389,11 +389,11 @@ if [ "${1}" = "release" -o "${1}" = "mkimage" -o "${1}" = "noobs" ]; then fi # Copy Bootloader - cp -PR ${BUILD}/bcm2835-bootloader-*/LICENCE* ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ - cp -PR ${BUILD}/bcm2835-bootloader-*/bootcode.bin ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ - cp -PR ${BUILD}/bcm2835-bootloader-*/fixup_x.dat ${RELEASE_DIR}/${NOOBS_DISTRO}/System/fixup.dat - cp -PR ${BUILD}/bcm2835-bootloader-*/start_x.elf ${RELEASE_DIR}/${NOOBS_DISTRO}/System/start.elf - [ -f ${BUILD}/bcm2835-bootloader-*/dt-blob.bin ] && cp -PR ${BUILD}/bcm2835-bootloader-*/dt-blob.bin ${RELEASE_DIR}/${NOOBS_DISTRO}/System/dt-blob.bin + cp -PR ${INSTALL}/usr/share/bootloader/LICENCE* ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ + cp -PR ${INSTALL}/usr/share/bootloader/bootcode.bin ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ + cp -PR ${INSTALL}/usr/share/bootloader/fixup.dat ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ + cp -PR ${INSTALL}/usr/share/bootloader/start.elf ${RELEASE_DIR}/${NOOBS_DISTRO}/System/ + [ -f ${INSTALL}/usr/share/bootloader/dt-blob.bin ] && cp -PR ${INSTALL}/usr/share/bootloader/dt-blob.bin ${RELEASE_DIR}/${NOOBS_DISTRO}/System/dt-blob.bin # Copy system files cp ${TARGET_IMG}/${IMAGE_NAME}.system ${RELEASE_DIR}/${NOOBS_DISTRO}/System/SYSTEM